mirror of
https://github.com/casdoor/casdoor.git
synced 2025-08-09 14:37:58 +08:00
Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
bfe8e5f3e7 | ||
![]() |
702ee6acd0 | ||
![]() |
0a9587901a | ||
![]() |
577bd6ce58 | ||
![]() |
3c4112dd44 | ||
![]() |
b7a37126ad | ||
![]() |
8669d5bb0d | ||
![]() |
aee3ea4981 | ||
![]() |
516f4b7569 | ||
![]() |
7d7ca10481 | ||
![]() |
a9d4978a0f | ||
![]() |
09f40bb5ce | ||
![]() |
a6f803aff1 | ||
![]() |
fc9528be43 | ||
![]() |
58e8f9f90b | ||
![]() |
e850e33f37 | ||
![]() |
d7110ff8bf |
@@ -48,14 +48,11 @@ func (c *ApiController) GetApplications() {
|
|||||||
} else {
|
} else {
|
||||||
applications, err = object.GetOrganizationApplications(owner, organization)
|
applications, err = object.GetOrganizationApplications(owner, organization)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
c.ResponseOk(object.GetMaskedApplications(applications, userId))
|
||||||
c.Data["json"] = object.GetMaskedApplications(applications, userId)
|
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
count, err := object.GetApplicationCount(owner, field, value)
|
count, err := object.GetApplicationCount(owner, field, value)
|
||||||
@@ -86,14 +83,14 @@ func (c *ApiController) GetApplications() {
|
|||||||
func (c *ApiController) GetApplication() {
|
func (c *ApiController) GetApplication() {
|
||||||
userId := c.GetSessionUsername()
|
userId := c.GetSessionUsername()
|
||||||
id := c.Input().Get("id")
|
id := c.Input().Get("id")
|
||||||
|
|
||||||
app, err := object.GetApplication(id)
|
app, err := object.GetApplication(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = object.GetMaskedApplication(app, userId)
|
c.ResponseOk(object.GetMaskedApplication(app, userId))
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserApplication
|
// GetUserApplication
|
||||||
@@ -106,25 +103,24 @@ func (c *ApiController) GetApplication() {
|
|||||||
func (c *ApiController) GetUserApplication() {
|
func (c *ApiController) GetUserApplication() {
|
||||||
userId := c.GetSessionUsername()
|
userId := c.GetSessionUsername()
|
||||||
id := c.Input().Get("id")
|
id := c.Input().Get("id")
|
||||||
|
|
||||||
user, err := object.GetUser(id)
|
user, err := object.GetUser(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if user == nil {
|
if user == nil {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), id))
|
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), id))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
app, err := object.GetApplicationByUser(user)
|
application, err := object.GetApplicationByUser(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = object.GetMaskedApplication(app, userId)
|
c.ResponseOk(object.GetMaskedApplication(application, userId))
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOrganizationApplications
|
// GetOrganizationApplications
|
||||||
@@ -157,8 +153,7 @@ func (c *ApiController) GetOrganizationApplications() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = object.GetMaskedApplications(applications, userId)
|
c.ResponseOk(object.GetMaskedApplications(applications, userId))
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
|
|
||||||
|
@@ -422,7 +422,7 @@ func (c *ApiController) Login() {
|
|||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if provider.Category == "OAuth" {
|
} else if provider.Category == "OAuth" || provider.Category == "Web3" {
|
||||||
// OAuth
|
// OAuth
|
||||||
idpInfo := object.FromProviderToIdpInfo(c.Ctx, provider)
|
idpInfo := object.FromProviderToIdpInfo(c.Ctx, provider)
|
||||||
idProvider := idp.GetIdProvider(idpInfo, authForm.RedirectUri)
|
idProvider := idp.GetIdProvider(idpInfo, authForm.RedirectUri)
|
||||||
@@ -465,7 +465,7 @@ func (c *ApiController) Login() {
|
|||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if provider.Category == "OAuth" {
|
} else if provider.Category == "OAuth" || provider.Category == "Web3" {
|
||||||
user, err = object.GetUserByField(application.Organization, provider.Type, userInfo.Id)
|
user, err = object.GetUserByField(application.Organization, provider.Type, userInfo.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
@@ -486,7 +486,7 @@ func (c *ApiController) Login() {
|
|||||||
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" || provider.Category == "Web3" {
|
||||||
// Sign up via OAuth
|
// Sign up via OAuth
|
||||||
if application.EnableLinkWithEmail {
|
if application.EnableLinkWithEmail {
|
||||||
if userInfo.Email != "" {
|
if userInfo.Email != "" {
|
||||||
|
@@ -45,8 +45,7 @@ func (c *ApiController) GetCerts() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = maskedCerts
|
c.ResponseOk(maskedCerts)
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
count, err := object.GetCertCount(owner, field, value)
|
count, err := object.GetCertCount(owner, field, value)
|
||||||
@@ -87,8 +86,7 @@ func (c *ApiController) GetGlobleCerts() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = maskedCerts
|
c.ResponseOk(maskedCerts)
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
count, err := object.GetGlobalCertsCount(field, value)
|
count, err := object.GetGlobalCertsCount(field, value)
|
||||||
@@ -123,8 +121,7 @@ func (c *ApiController) GetCert() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = object.GetMaskedCert(cert)
|
c.ResponseOk(object.GetMaskedCert(cert))
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateCert
|
// UpdateCert
|
||||||
|
@@ -45,8 +45,7 @@ func (c *ApiController) GetChats() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = maskedChats
|
c.ResponseOk(maskedChats)
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
count, err := object.GetChatCount(owner, field, value)
|
count, err := object.GetChatCount(owner, field, value)
|
||||||
@@ -82,8 +81,7 @@ func (c *ApiController) GetChat() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = maskedChat
|
c.ResponseOk(maskedChat)
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateChat
|
// UpdateChat
|
||||||
|
@@ -82,9 +82,9 @@ func (c *ApiController) GetGroup() {
|
|||||||
group, err := object.GetGroup(id)
|
group, err := object.GetGroup(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
} else {
|
return
|
||||||
c.ResponseOk(group)
|
|
||||||
}
|
}
|
||||||
|
c.ResponseOk(group)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateGroup
|
// UpdateGroup
|
||||||
|
@@ -125,7 +125,12 @@ func (c *ApiController) GetLdap() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_, name := util.GetOwnerAndNameFromId(id)
|
_, name := util.GetOwnerAndNameFromId(id)
|
||||||
c.ResponseOk(object.GetMaskedLdap(object.GetLdap(name)))
|
ldap, err := object.GetLdap(name)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.ResponseOk(object.GetMaskedLdap(ldap))
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddLdap
|
// AddLdap
|
||||||
|
@@ -57,8 +57,7 @@ func (c *ApiController) GetMessages() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = object.GetMaskedMessages(messages)
|
c.ResponseOk(object.GetMaskedMessages(messages))
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
count, err := object.GetMessageCount(owner, organization, field, value)
|
count, err := object.GetMessageCount(owner, organization, field, value)
|
||||||
@@ -94,8 +93,7 @@ func (c *ApiController) GetMessage() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = object.GetMaskedMessage(message)
|
c.ResponseOk(message)
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ApiController) ResponseErrorStream(errorText string) {
|
func (c *ApiController) ResponseErrorStream(errorText string) {
|
||||||
|
@@ -45,8 +45,7 @@ func (c *ApiController) GetModels() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = models
|
c.ResponseOk(models)
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
count, err := object.GetModelCount(owner, field, value)
|
count, err := object.GetModelCount(owner, field, value)
|
||||||
@@ -82,8 +81,7 @@ func (c *ApiController) GetModel() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = model
|
c.ResponseOk(model)
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateModel
|
// UpdateModel
|
||||||
|
@@ -55,8 +55,7 @@ func (c *ApiController) GetOrganizations() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = maskedOrganizations
|
c.ResponseOk(maskedOrganizations)
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
if !isGlobalAdmin {
|
if !isGlobalAdmin {
|
||||||
maskedOrganizations, err := object.GetMaskedOrganizations(object.GetOrganizations(owner, c.getCurrentUser().Owner))
|
maskedOrganizations, err := object.GetMaskedOrganizations(object.GetOrganizations(owner, c.getCurrentUser().Owner))
|
||||||
@@ -184,6 +183,8 @@ func (c *ApiController) DeleteOrganization() {
|
|||||||
func (c *ApiController) GetDefaultApplication() {
|
func (c *ApiController) GetDefaultApplication() {
|
||||||
userId := c.GetSessionUsername()
|
userId := c.GetSessionUsername()
|
||||||
id := c.Input().Get("id")
|
id := c.Input().Get("id")
|
||||||
|
redirectUri := c.Input().Get("redirectUri")
|
||||||
|
typ := c.Input().Get("type")
|
||||||
|
|
||||||
application, err := object.GetDefaultApplication(id)
|
application, err := object.GetDefaultApplication(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -191,6 +192,14 @@ func (c *ApiController) GetDefaultApplication() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if typ == "cas" {
|
||||||
|
err = object.CheckCasRestrict(application, c.GetAcceptLanguage(), redirectUri)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
maskedApplication := object.GetMaskedApplication(application, userId)
|
maskedApplication := object.GetMaskedApplication(application, userId)
|
||||||
c.ResponseOk(maskedApplication)
|
c.ResponseOk(maskedApplication)
|
||||||
}
|
}
|
||||||
|
@@ -46,8 +46,7 @@ func (c *ApiController) GetPayments() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = payments
|
c.ResponseOk(payments)
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
count, err := object.GetPaymentCount(owner, organization, field, value)
|
count, err := object.GetPaymentCount(owner, organization, field, value)
|
||||||
@@ -106,8 +105,7 @@ func (c *ApiController) GetPayment() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = payment
|
c.ResponseOk(payment)
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdatePayment
|
// UpdatePayment
|
||||||
|
@@ -45,8 +45,7 @@ func (c *ApiController) GetPermissions() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = permissions
|
c.ResponseOk(permissions)
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
count, err := object.GetPermissionCount(owner, field, value)
|
count, err := object.GetPermissionCount(owner, field, value)
|
||||||
@@ -85,7 +84,6 @@ func (c *ApiController) GetPermissionsBySubmitter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.ResponseOk(permissions, len(permissions))
|
c.ResponseOk(permissions, len(permissions))
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPermissionsByRole
|
// GetPermissionsByRole
|
||||||
@@ -104,7 +102,6 @@ func (c *ApiController) GetPermissionsByRole() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.ResponseOk(permissions, len(permissions))
|
c.ResponseOk(permissions, len(permissions))
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPermission
|
// GetPermission
|
||||||
@@ -123,8 +120,7 @@ func (c *ApiController) GetPermission() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = permission
|
c.ResponseOk(permission)
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdatePermission
|
// UpdatePermission
|
||||||
|
@@ -45,8 +45,7 @@ func (c *ApiController) GetPlans() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = plans
|
c.ResponseOk(plans)
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
count, err := object.GetPlanCount(owner, field, value)
|
count, err := object.GetPlanCount(owner, field, value)
|
||||||
@@ -95,11 +94,10 @@ func (c *ApiController) GetPlan() {
|
|||||||
plan.Options = append(plan.Options, option.DisplayName)
|
plan.Options = append(plan.Options, option.DisplayName)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = plan
|
c.ResponseOk(plan)
|
||||||
} else {
|
} else {
|
||||||
c.Data["json"] = plan
|
c.ResponseOk(plan)
|
||||||
}
|
}
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdatePlan
|
// UpdatePlan
|
||||||
|
@@ -45,8 +45,7 @@ func (c *ApiController) GetPricings() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = pricings
|
c.ResponseOk(pricings)
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
count, err := object.GetPricingCount(owner, field, value)
|
count, err := object.GetPricingCount(owner, field, value)
|
||||||
@@ -82,8 +81,7 @@ func (c *ApiController) GetPricing() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = pricing
|
c.ResponseOk(pricing)
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdatePricing
|
// UpdatePricing
|
||||||
|
@@ -46,8 +46,7 @@ func (c *ApiController) GetProducts() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = products
|
c.ResponseOk(products)
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
count, err := object.GetProductCount(owner, field, value)
|
count, err := object.GetProductCount(owner, field, value)
|
||||||
@@ -89,8 +88,7 @@ func (c *ApiController) GetProduct() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = product
|
c.ResponseOk(product)
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateProduct
|
// UpdateProduct
|
||||||
|
@@ -51,8 +51,7 @@ func (c *ApiController) GetRecords() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = records
|
c.ResponseOk(records)
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
if c.IsGlobalAdmin() && organizationName != "" {
|
if c.IsGlobalAdmin() && organizationName != "" {
|
||||||
@@ -99,8 +98,7 @@ func (c *ApiController) GetRecordsByFilter() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = records
|
c.ResponseOk(records)
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddRecord
|
// AddRecord
|
||||||
|
@@ -67,8 +67,7 @@ func (c *ApiController) GetResources() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = resources
|
c.ResponseOk(resources)
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
count, err := object.GetResourceCount(owner, user, field, value)
|
count, err := object.GetResourceCount(owner, user, field, value)
|
||||||
@@ -104,8 +103,7 @@ func (c *ApiController) GetResource() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = resource
|
c.ResponseOk(resource)
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateResource
|
// UpdateResource
|
||||||
|
@@ -45,8 +45,7 @@ func (c *ApiController) GetRoles() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = roles
|
c.ResponseOk(roles)
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
count, err := object.GetRoleCount(owner, field, value)
|
count, err := object.GetRoleCount(owner, field, value)
|
||||||
@@ -82,8 +81,7 @@ func (c *ApiController) GetRole() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = role
|
c.ResponseOk(role)
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateRole
|
// UpdateRole
|
||||||
|
@@ -45,8 +45,7 @@ func (c *ApiController) GetSessions() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = sessions
|
c.ResponseOk(sessions)
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
count, err := object.GetSessionCount(owner, field, value)
|
count, err := object.GetSessionCount(owner, field, value)
|
||||||
@@ -81,8 +80,7 @@ func (c *ApiController) GetSingleSession() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = session
|
c.ResponseOk(session)
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateSession
|
// UpdateSession
|
||||||
@@ -161,7 +159,5 @@ func (c *ApiController) IsSessionDuplicated() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = &Response{Status: "ok", Msg: "", Data: isUserSessionDuplicated}
|
c.ResponseOk(isUserSessionDuplicated)
|
||||||
|
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
@@ -45,8 +45,7 @@ func (c *ApiController) GetSubscriptions() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = subscriptions
|
c.ResponseOk(subscriptions)
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
count, err := object.GetSubscriptionCount(owner, field, value)
|
count, err := object.GetSubscriptionCount(owner, field, value)
|
||||||
@@ -82,8 +81,7 @@ func (c *ApiController) GetSubscription() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = subscription
|
c.ResponseOk(subscription)
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateSubscription
|
// UpdateSubscription
|
||||||
|
@@ -46,8 +46,7 @@ func (c *ApiController) GetSyncers() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = organizationSyncers
|
c.ResponseOk(organizationSyncers)
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
count, err := object.GetSyncerCount(owner, organization, field, value)
|
count, err := object.GetSyncerCount(owner, organization, field, value)
|
||||||
@@ -83,8 +82,7 @@ func (c *ApiController) GetSyncer() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = syncer
|
c.ResponseOk(syncer)
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateSyncer
|
// UpdateSyncer
|
||||||
|
@@ -47,8 +47,7 @@ func (c *ApiController) GetTokens() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = token
|
c.ResponseOk(token)
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
count, err := object.GetTokenCount(owner, organization, field, value)
|
count, err := object.GetTokenCount(owner, organization, field, value)
|
||||||
@@ -83,8 +82,7 @@ func (c *ApiController) GetToken() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = token
|
c.ResponseOk(token)
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateToken
|
// UpdateToken
|
||||||
|
@@ -45,8 +45,7 @@ func (c *ApiController) GetGlobalUsers() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = maskedUsers
|
c.ResponseOk(maskedUsers)
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
count, err := object.GetGlobalUserCount(field, value)
|
count, err := object.GetGlobalUserCount(field, value)
|
||||||
@@ -106,8 +105,7 @@ func (c *ApiController) GetUsers() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = maskedUsers
|
c.ResponseOk(maskedUsers)
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
count, err := object.GetUserCount(owner, field, value, groupName)
|
count, err := object.GetUserCount(owner, field, value, groupName)
|
||||||
@@ -215,8 +213,7 @@ func (c *ApiController) GetUser() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = maskedUser
|
c.ResponseOk(maskedUser)
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateUser
|
// UpdateUser
|
||||||
@@ -513,8 +510,7 @@ func (c *ApiController) GetSortedUsers() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = maskedUsers
|
c.ResponseOk(maskedUsers)
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserCount
|
// GetUserCount
|
||||||
@@ -541,8 +537,7 @@ func (c *ApiController) GetUserCount() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = count
|
c.ResponseOk(count)
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddUserkeys
|
// AddUserkeys
|
||||||
|
@@ -46,8 +46,7 @@ func (c *ApiController) GetWebhooks() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = webhooks
|
c.ResponseOk(webhooks)
|
||||||
c.ServeJSON()
|
|
||||||
} else {
|
} else {
|
||||||
limit := util.ParseInt(limit)
|
limit := util.ParseInt(limit)
|
||||||
count, err := object.GetWebhookCount(owner, organization, field, value)
|
count, err := object.GetWebhookCount(owner, organization, field, value)
|
||||||
@@ -84,8 +83,7 @@ func (c *ApiController) GetWebhook() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = webhook
|
c.ResponseOk(webhook)
|
||||||
c.ServeJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateWebhook
|
// UpdateWebhook
|
||||||
|
2
go.sum
2
go.sum
@@ -546,8 +546,6 @@ github.com/russellhaering/goxmldsig v1.2.0 h1:Y6GTTc9Un5hCxSzVz4UIWQ/zuVwDvzJk80
|
|||||||
github.com/russellhaering/goxmldsig v1.2.0/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWydB7n0KkEubVJl+Tw=
|
github.com/russellhaering/goxmldsig v1.2.0/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWydB7n0KkEubVJl+Tw=
|
||||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/sashabaranov/go-openai v1.9.1 h1:3N52HkJKo9Zlo/oe1AVv5ZkCOny0ra58/ACvAxkN3MM=
|
|
||||||
github.com/sashabaranov/go-openai v1.9.1/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
|
||||||
github.com/sashabaranov/go-openai v1.12.0 h1:aRNHH0gtVfrpIaEolD0sWrLLRnYQNK4cH/bIAHwL8Rk=
|
github.com/sashabaranov/go-openai v1.12.0 h1:aRNHH0gtVfrpIaEolD0sWrLLRnYQNK4cH/bIAHwL8Rk=
|
||||||
github.com/sashabaranov/go-openai v1.12.0/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
github.com/sashabaranov/go-openai v1.12.0/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
||||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||||
|
80
idp/metamask.go
Normal file
80
idp/metamask.go
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
package idp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
)
|
||||||
|
|
||||||
|
const Web3AuthTokenKey = "web3AuthToken"
|
||||||
|
|
||||||
|
type MetaMaskIdProvider struct {
|
||||||
|
Client *http.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
type Web3AuthToken struct {
|
||||||
|
Address string `json:"address"`
|
||||||
|
Nonce string `json:"nonce"`
|
||||||
|
CreateAt uint64 `json:"createAt"`
|
||||||
|
TypedData string `json:"typedData"`
|
||||||
|
Signature string `json:"signature"` // signature for typed data
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMetaMaskIdProvider() *MetaMaskIdProvider {
|
||||||
|
idp := &MetaMaskIdProvider{}
|
||||||
|
return idp
|
||||||
|
}
|
||||||
|
|
||||||
|
func (idp *MetaMaskIdProvider) SetHttpClient(client *http.Client) {
|
||||||
|
idp.Client = client
|
||||||
|
}
|
||||||
|
|
||||||
|
func (idp *MetaMaskIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||||
|
web3AuthToken := Web3AuthToken{}
|
||||||
|
if err := json.Unmarshal([]byte(code), &web3AuthToken); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
token := &oauth2.Token{
|
||||||
|
AccessToken: web3AuthToken.Signature,
|
||||||
|
TokenType: "Bearer",
|
||||||
|
Expiry: time.Now().AddDate(0, 1, 0),
|
||||||
|
}
|
||||||
|
|
||||||
|
token = token.WithExtra(map[string]interface{}{
|
||||||
|
Web3AuthTokenKey: web3AuthToken,
|
||||||
|
})
|
||||||
|
return token, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (idp *MetaMaskIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||||
|
// TODO use "github.com/ethereum/go-ethereum" to check address's eth balance or transaction
|
||||||
|
web3AuthToken, ok := token.Extra(Web3AuthTokenKey).(Web3AuthToken)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("invalid web3AuthToken")
|
||||||
|
}
|
||||||
|
userInfo := &UserInfo{
|
||||||
|
Id: web3AuthToken.Address,
|
||||||
|
Username: web3AuthToken.Address,
|
||||||
|
DisplayName: web3AuthToken.Address,
|
||||||
|
AvatarUrl: fmt.Sprintf("metamask:%v", web3AuthToken.Address),
|
||||||
|
}
|
||||||
|
return userInfo, nil
|
||||||
|
}
|
@@ -109,6 +109,8 @@ func GetIdProvider(idpInfo *ProviderInfo, redirectUrl string) IdProvider {
|
|||||||
return NewDouyinIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
return NewDouyinIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
||||||
case "Bilibili":
|
case "Bilibili":
|
||||||
return NewBilibiliIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
return NewBilibiliIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
||||||
|
case "MetaMask":
|
||||||
|
return NewMetaMaskIdProvider()
|
||||||
default:
|
default:
|
||||||
if isGothSupport(idpInfo.Type) {
|
if isGothSupport(idpInfo.Type) {
|
||||||
return NewGothIdProvider(idpInfo.Type, idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl, idpInfo.HostUrl)
|
return NewGothIdProvider(idpInfo.Type, idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl, idpInfo.HostUrl)
|
||||||
|
@@ -34,7 +34,7 @@ func StartLdapServer() {
|
|||||||
server.Handle(routes)
|
server.Handle(routes)
|
||||||
err := server.ListenAndServe("0.0.0.0:" + conf.GetConfigString("ldapServerPort"))
|
err := server.ListenAndServe("0.0.0.0:" + conf.GetConfigString("ldapServerPort"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
log.Printf("StartLdapServer() failed, ErrMsg = %s", err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,8 +15,10 @@
|
|||||||
package object
|
package object
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/beego/beego"
|
"github.com/beego/beego"
|
||||||
"github.com/casdoor/casdoor/conf"
|
"github.com/casdoor/casdoor/conf"
|
||||||
@@ -46,6 +48,11 @@ func InitConfig() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func InitAdapter() {
|
func InitAdapter() {
|
||||||
|
err := createDatabaseForPostgres(conf.GetConfigString("driverName"), conf.GetConfigDataSourceName(), conf.GetConfigString("dbName"))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
adapter = NewAdapter(conf.GetConfigString("driverName"), conf.GetConfigDataSourceName(), conf.GetConfigString("dbName"))
|
adapter = NewAdapter(conf.GetConfigString("driverName"), conf.GetConfigDataSourceName(), conf.GetConfigString("dbName"))
|
||||||
|
|
||||||
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
|
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
|
||||||
@@ -96,7 +103,32 @@ func NewAdapter(driverName string, dataSourceName string, dbName string) *Adapte
|
|||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createDatabaseForPostgres(driverName string, dataSourceName string, dbName string) error {
|
||||||
|
if driverName == "postgres" {
|
||||||
|
db, err := sql.Open(driverName, dataSourceName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
_, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s;", dbName))
|
||||||
|
if err != nil {
|
||||||
|
if !strings.Contains(err.Error(), "already exists") {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (a *Adapter) CreateDatabase() error {
|
func (a *Adapter) CreateDatabase() error {
|
||||||
|
if a.driverName == "postgres" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
engine, err := xorm.NewEngine(a.driverName, a.dataSourceName)
|
engine, err := xorm.NewEngine(a.driverName, a.dataSourceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@@ -161,5 +161,8 @@ func modelChangeTrigger(oldName string, newName string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func HasRoleDefinition(m model.Model) bool {
|
func HasRoleDefinition(m model.Model) bool {
|
||||||
|
if m == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return m["g"] != nil
|
return m["g"] != nil
|
||||||
}
|
}
|
||||||
|
@@ -26,42 +26,7 @@ import (
|
|||||||
xormadapter "github.com/casdoor/xorm-adapter/v3"
|
xormadapter "github.com/casdoor/xorm-adapter/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getEnforcer(permission *Permission, permissionIDs ...string) *casbin.Enforcer {
|
func getEnforcer(p *Permission, permissionIDs ...string) *casbin.Enforcer {
|
||||||
tableName := "permission_rule"
|
|
||||||
if len(permission.Adapter) != 0 {
|
|
||||||
adapterObj, err := getCasbinAdapter(permission.Owner, permission.Adapter)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if adapterObj != nil && adapterObj.Table != "" {
|
|
||||||
tableName = adapterObj.Table
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
|
|
||||||
driverName := conf.GetConfigString("driverName")
|
|
||||||
dataSourceName := conf.GetConfigRealDataSourceName(driverName)
|
|
||||||
adapter, err := xormadapter.NewAdapterWithTableName(driverName, dataSourceName, tableName, tableNamePrefix, true)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
permissionModel, err := getModel(permission.Owner, permission.Model)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
m := model.Model{}
|
|
||||||
if permissionModel != nil {
|
|
||||||
m, err = GetBuiltInModel(permissionModel.ModelText)
|
|
||||||
} else {
|
|
||||||
m, err = GetBuiltInModel("")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init an enforcer instance without specifying a model or adapter.
|
// Init an enforcer instance without specifying a model or adapter.
|
||||||
// If you specify an adapter, it will load all policies, which is a
|
// If you specify an adapter, it will load all policies, which is a
|
||||||
// heavy process that can slow down the application.
|
// heavy process that can slow down the application.
|
||||||
@@ -70,14 +35,17 @@ func getEnforcer(permission *Permission, permissionIDs ...string) *casbin.Enforc
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = enforcer.InitWithModelAndAdapter(m, nil)
|
err = p.setEnforcerModel(enforcer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
enforcer.SetAdapter(adapter)
|
err = p.setEnforcerAdapter(enforcer)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
policyFilterV5 := []string{permission.GetId()}
|
policyFilterV5 := []string{p.GetId()}
|
||||||
if len(permissionIDs) != 0 {
|
if len(permissionIDs) != 0 {
|
||||||
policyFilterV5 = permissionIDs
|
policyFilterV5 = permissionIDs
|
||||||
}
|
}
|
||||||
@@ -86,7 +54,7 @@ func getEnforcer(permission *Permission, permissionIDs ...string) *casbin.Enforc
|
|||||||
V5: policyFilterV5,
|
V5: policyFilterV5,
|
||||||
}
|
}
|
||||||
|
|
||||||
if !HasRoleDefinition(m) {
|
if !HasRoleDefinition(enforcer.GetModel()) {
|
||||||
policyFilter.Ptype = []string{"p"}
|
policyFilter.Ptype = []string{"p"}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,35 +66,70 @@ func getEnforcer(permission *Permission, permissionIDs ...string) *casbin.Enforc
|
|||||||
return enforcer
|
return enforcer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Permission) setEnforcerAdapter(enforcer *casbin.Enforcer) error {
|
||||||
|
tableName := "permission_rule"
|
||||||
|
if len(p.Adapter) != 0 {
|
||||||
|
adapterObj, err := getCasbinAdapter(p.Owner, p.Adapter)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if adapterObj != nil && adapterObj.Table != "" {
|
||||||
|
tableName = adapterObj.Table
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
|
||||||
|
driverName := conf.GetConfigString("driverName")
|
||||||
|
dataSourceName := conf.GetConfigRealDataSourceName(driverName)
|
||||||
|
casbinAdapter, err := xormadapter.NewAdapterWithTableName(driverName, dataSourceName, tableName, tableNamePrefix, true)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
enforcer.SetAdapter(casbinAdapter)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Permission) setEnforcerModel(enforcer *casbin.Enforcer) error {
|
||||||
|
permissionModel, err := getModel(p.Owner, p.Model)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: return error if permissionModel is nil.
|
||||||
|
m := model.Model{}
|
||||||
|
if permissionModel != nil {
|
||||||
|
m, err = GetBuiltInModel(permissionModel.ModelText)
|
||||||
|
} else {
|
||||||
|
m, err = GetBuiltInModel("")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = enforcer.InitWithModelAndAdapter(m, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func getPolicies(permission *Permission) [][]string {
|
func getPolicies(permission *Permission) [][]string {
|
||||||
var policies [][]string
|
var policies [][]string
|
||||||
|
|
||||||
permissionId := permission.GetId()
|
permissionId := permission.GetId()
|
||||||
domainExist := len(permission.Domains) > 0
|
domainExist := len(permission.Domains) > 0
|
||||||
|
|
||||||
for _, user := range permission.Users {
|
usersAndRoles := append(permission.Users, permission.Roles...)
|
||||||
|
for _, userOrRole := range usersAndRoles {
|
||||||
for _, resource := range permission.Resources {
|
for _, resource := range permission.Resources {
|
||||||
for _, action := range permission.Actions {
|
for _, action := range permission.Actions {
|
||||||
if domainExist {
|
if domainExist {
|
||||||
for _, domain := range permission.Domains {
|
for _, domain := range permission.Domains {
|
||||||
policies = append(policies, []string{user, domain, resource, strings.ToLower(action), permission.Effect, permissionId})
|
policies = append(policies, []string{userOrRole, domain, resource, strings.ToLower(action), strings.ToLower(permission.Effect), permissionId})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
policies = append(policies, []string{user, resource, strings.ToLower(action), permission.Effect, "", permissionId})
|
policies = append(policies, []string{userOrRole, resource, strings.ToLower(action), strings.ToLower(permission.Effect), "", permissionId})
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, role := range permission.Roles {
|
|
||||||
for _, resource := range permission.Resources {
|
|
||||||
for _, action := range permission.Actions {
|
|
||||||
if domainExist {
|
|
||||||
for _, domain := range permission.Domains {
|
|
||||||
policies = append(policies, []string{role, domain, resource, strings.ToLower(action), "", permissionId})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
policies = append(policies, []string{role, resource, strings.ToLower(action), "", "", permissionId})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -49,7 +49,7 @@ func (pi *ProviderItem) IsProviderVisible() bool {
|
|||||||
if pi.Provider == nil {
|
if pi.Provider == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return pi.Provider.Category == "OAuth" || pi.Provider.Category == "SAML"
|
return pi.Provider.Category == "OAuth" || pi.Provider.Category == "SAML" || pi.Provider.Category == "Web3"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pi *ProviderItem) isProviderPrompted() bool {
|
func (pi *ProviderItem) isProviderPrompted() bool {
|
||||||
|
@@ -16,6 +16,7 @@ package object
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
"github.com/xorm-io/core"
|
"github.com/xorm-io/core"
|
||||||
@@ -76,6 +77,10 @@ func GetPaginationResources(owner, user string, offset, limit int, field, value,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getResource(owner string, name string) (*Resource, error) {
|
func getResource(owner string, name string) (*Resource, error) {
|
||||||
|
if !strings.HasPrefix(name, "/") {
|
||||||
|
name = "/" + name
|
||||||
|
}
|
||||||
|
|
||||||
resource := Resource{Owner: owner, Name: name}
|
resource := Resource{Owner: owner, Name: name}
|
||||||
existed, err := adapter.Engine.Get(&resource)
|
existed, err := adapter.Engine.Get(&resource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -26,6 +26,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/beevik/etree"
|
"github.com/beevik/etree"
|
||||||
|
"github.com/casdoor/casdoor/i18n"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
dsig "github.com/russellhaering/goxmldsig"
|
dsig "github.com/russellhaering/goxmldsig"
|
||||||
)
|
)
|
||||||
@@ -122,6 +123,13 @@ var stToServiceResponse sync.Map
|
|||||||
// pgt is short for proxy granting ticket
|
// pgt is short for proxy granting ticket
|
||||||
var pgtToServiceResponse sync.Map
|
var pgtToServiceResponse sync.Map
|
||||||
|
|
||||||
|
func CheckCasRestrict(application *Application, lang string, service string) error {
|
||||||
|
if len(application.RedirectUris) > 0 && !application.IsRedirectUriValid(service) {
|
||||||
|
return fmt.Errorf(i18n.Translate(lang, "token:Redirect URI: %s doesn't exist in the allowed Redirect URI list"), service)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func StoreCasTokenForPgt(token *CasAuthenticationSuccess, service, userId string) string {
|
func StoreCasTokenForPgt(token *CasAuthenticationSuccess, service, userId string) string {
|
||||||
pgt := fmt.Sprintf("PGT-%s", util.GenerateId())
|
pgt := fmt.Sprintf("PGT-%s", util.GenerateId())
|
||||||
pgtToServiceResponse.Store(pgt, &CasAuthenticationSuccessWrapper{
|
pgtToServiceResponse.Store(pgt, &CasAuthenticationSuccessWrapper{
|
||||||
|
@@ -281,6 +281,14 @@ func generateJwtToken(application *Application, user *User, nonce string, scope
|
|||||||
return "", "", "", err
|
return "", "", "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cert == nil {
|
||||||
|
if application.Cert == "" {
|
||||||
|
return "", "", "", fmt.Errorf("The cert field of the application \"%s\" should not be empty", application.GetId())
|
||||||
|
} else {
|
||||||
|
return "", "", "", fmt.Errorf("The cert \"%s\" does not exist", application.Cert)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// RSA private key
|
// RSA private key
|
||||||
key, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(cert.PrivateKey))
|
key, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(cert.PrivateKey))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -156,6 +156,7 @@ type User struct {
|
|||||||
Yammer string `xorm:"yammer varchar(100)" json:"yammer"`
|
Yammer string `xorm:"yammer varchar(100)" json:"yammer"`
|
||||||
Yandex string `xorm:"yandex varchar(100)" json:"yandex"`
|
Yandex string `xorm:"yandex varchar(100)" json:"yandex"`
|
||||||
Zoom string `xorm:"zoom varchar(100)" json:"zoom"`
|
Zoom string `xorm:"zoom varchar(100)" json:"zoom"`
|
||||||
|
MetaMask string `xorm:"metamask varchar(100)" json:"metamask"`
|
||||||
Custom string `xorm:"custom varchar(100)" json:"custom"`
|
Custom string `xorm:"custom varchar(100)" json:"custom"`
|
||||||
|
|
||||||
WebauthnCredentials []webauthn.Credential `xorm:"webauthnCredentials blob" json:"webauthnCredentials"`
|
WebauthnCredentials []webauthn.Credential `xorm:"webauthnCredentials blob" json:"webauthnCredentials"`
|
||||||
|
@@ -156,7 +156,7 @@ func AuthzFilter(ctx *context.Context) {
|
|||||||
urlPath := getUrlPath(ctx.Request.URL.Path)
|
urlPath := getUrlPath(ctx.Request.URL.Path)
|
||||||
|
|
||||||
objOwner, objName := "", ""
|
objOwner, objName := "", ""
|
||||||
if urlPath != "/api/get-app-login" {
|
if urlPath != "/api/get-app-login" && urlPath != "/api/get-resource" {
|
||||||
objOwner, objName = getObject(ctx)
|
objOwner, objName = getObject(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -23,7 +23,7 @@ func GetStorageProvider(providerType string, clientId string, clientSecret strin
|
|||||||
case "AWS S3":
|
case "AWS S3":
|
||||||
return NewAwsS3StorageProvider(clientId, clientSecret, region, bucket, endpoint)
|
return NewAwsS3StorageProvider(clientId, clientSecret, region, bucket, endpoint)
|
||||||
case "MinIO":
|
case "MinIO":
|
||||||
return NewMinIOS3StorageProvider(clientId, clientSecret, region, bucket, endpoint)
|
return NewMinIOS3StorageProvider(clientId, clientSecret, "_", bucket, endpoint)
|
||||||
case "Aliyun OSS":
|
case "Aliyun OSS":
|
||||||
return NewAliyunOssStorageProvider(clientId, clientSecret, region, bucket, endpoint)
|
return NewAliyunOssStorageProvider(clientId, clientSecret, region, bucket, endpoint)
|
||||||
case "Tencent Cloud COS":
|
case "Tencent Cloud COS":
|
||||||
|
@@ -50,4 +50,32 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
webpack: {
|
||||||
|
// use polyfill Buffer with Webpack 5
|
||||||
|
// https://viglucci.io/articles/how-to-polyfill-buffer-with-webpack-5
|
||||||
|
// https://craco.js.org/docs/configuration/webpack/
|
||||||
|
configure: (webpackConfig, { env, paths }) => {
|
||||||
|
webpackConfig.resolve.fallback = {
|
||||||
|
// "process": require.resolve('process/browser'),
|
||||||
|
// "util": require.resolve("util/"),
|
||||||
|
// "url": require.resolve("url/"),
|
||||||
|
// "zlib": require.resolve("browserify-zlib"),
|
||||||
|
// "stream": require.resolve("stream-browserify"),
|
||||||
|
// "http": require.resolve("stream-http"),
|
||||||
|
// "https": require.resolve("https-browserify"),
|
||||||
|
// "assert": require.resolve("assert/"),
|
||||||
|
"buffer": require.resolve('buffer/'),
|
||||||
|
"process": false,
|
||||||
|
"util": false,
|
||||||
|
"url": false,
|
||||||
|
"zlib": false,
|
||||||
|
"stream": false,
|
||||||
|
"http": false,
|
||||||
|
"https": false,
|
||||||
|
"assert": false,
|
||||||
|
"buffer": false,
|
||||||
|
};
|
||||||
|
return webpackConfig;
|
||||||
|
},
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@@ -9,11 +9,13 @@
|
|||||||
"@crowdin/cli": "^3.7.10",
|
"@crowdin/cli": "^3.7.10",
|
||||||
"@ctrl/tinycolor": "^3.5.0",
|
"@ctrl/tinycolor": "^3.5.0",
|
||||||
"@emotion/react": "^11.10.5",
|
"@emotion/react": "^11.10.5",
|
||||||
|
"@metamask/eth-sig-util": "^6.0.0",
|
||||||
"@testing-library/jest-dom": "^4.2.4",
|
"@testing-library/jest-dom": "^4.2.4",
|
||||||
"@testing-library/react": "^9.3.2",
|
"@testing-library/react": "^9.3.2",
|
||||||
"@testing-library/user-event": "^7.1.2",
|
"@testing-library/user-event": "^7.1.2",
|
||||||
"antd": "5.2.3",
|
"antd": "5.2.3",
|
||||||
"antd-token-previewer": "^1.1.0-22",
|
"antd-token-previewer": "^1.1.0-22",
|
||||||
|
"buffer": "^6.0.3",
|
||||||
"codemirror": "^5.61.1",
|
"codemirror": "^5.61.1",
|
||||||
"copy-to-clipboard": "^3.3.1",
|
"copy-to-clipboard": "^3.3.1",
|
||||||
"core-js": "^3.25.0",
|
"core-js": "^3.25.0",
|
||||||
@@ -34,6 +36,7 @@
|
|||||||
"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",
|
||||||
|
"react-metamask-avatar": "^1.2.1",
|
||||||
"react-router-dom": "^5.3.3",
|
"react-router-dom": "^5.3.3",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"react-social-login-buttons": "^3.4.0"
|
"react-social-login-buttons": "^3.4.0"
|
||||||
|
@@ -68,7 +68,7 @@ class AdapterEditPage extends React.Component {
|
|||||||
OrganizationBackend.getOrganizations("admin")
|
OrganizationBackend.getOrganizations("admin")
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
organizations: (res.msg === undefined) ? res : [],
|
organizations: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -80,8 +80,9 @@ class AdapterEditPage extends React.Component {
|
|||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
models: res,
|
models: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -89,6 +89,8 @@ import {withTranslation} from "react-i18next";
|
|||||||
import LanguageSelect from "./common/select/LanguageSelect";
|
import LanguageSelect from "./common/select/LanguageSelect";
|
||||||
import ThemeSelect from "./common/select/ThemeSelect";
|
import ThemeSelect from "./common/select/ThemeSelect";
|
||||||
import OrganizationSelect from "./common/select/OrganizationSelect";
|
import OrganizationSelect from "./common/select/OrganizationSelect";
|
||||||
|
import {clearWeb3AuthToken} from "./auth/Web3Auth";
|
||||||
|
import AccountAvatar from "./account/AccountAvatar";
|
||||||
|
|
||||||
const {Header, Footer, Content} = Layout;
|
const {Header, Footer, Content} = Layout;
|
||||||
|
|
||||||
@@ -312,12 +314,11 @@ class App extends Component {
|
|||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
const owner = this.state.account.owner;
|
const owner = this.state.account.owner;
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
account: null,
|
account: null,
|
||||||
themeAlgorithm: ["default"],
|
themeAlgorithm: ["default"],
|
||||||
});
|
});
|
||||||
|
clearWeb3AuthToken();
|
||||||
Setting.showMessage("success", i18next.t("application:Logged out successfully"));
|
Setting.showMessage("success", i18next.t("application:Logged out successfully"));
|
||||||
const redirectUri = res.data2;
|
const redirectUri = res.data2;
|
||||||
if (redirectUri !== null && redirectUri !== undefined && redirectUri !== "") {
|
if (redirectUri !== null && redirectUri !== undefined && redirectUri !== "") {
|
||||||
@@ -348,7 +349,9 @@ class App extends Component {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<Avatar src={this.state.account.avatar} style={{verticalAlign: "middle"}} size="large">
|
<Avatar src={this.state.account.avatar} style={{verticalAlign: "middle"}} size="large"
|
||||||
|
icon={<AccountAvatar src={this.state.account.avatar} style={{verticalAlign: "middle"}} size={40} />}
|
||||||
|
>
|
||||||
{Setting.getShortName(this.state.account.name)}
|
{Setting.getShortName(this.state.account.name)}
|
||||||
</Avatar>
|
</Avatar>
|
||||||
);
|
);
|
||||||
|
@@ -119,7 +119,7 @@ class ApplicationEditPage extends React.Component {
|
|||||||
getApplication() {
|
getApplication() {
|
||||||
ApplicationBackend.getApplication("admin", this.state.applicationName)
|
ApplicationBackend.getApplication("admin", this.state.applicationName)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res === null) {
|
if (res.data === null) {
|
||||||
this.props.history.push("/404");
|
this.props.history.push("/404");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -129,32 +129,33 @@ class ApplicationEditPage extends React.Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.grantTypes === null || res.grantTypes === undefined || res.grantTypes.length === 0) {
|
const application = res.data;
|
||||||
res.grantTypes = ["authorization_code"];
|
if (application.grantTypes === null || application.grantTypes === undefined || application.grantTypes.length === 0) {
|
||||||
|
application.grantTypes = ["authorization_code"];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.tags === null || res.tags === undefined) {
|
if (application.tags === null || application.tags === undefined) {
|
||||||
res.tags = [];
|
application.tags = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
application: res,
|
application: application,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.getCerts(res.organization);
|
this.getCerts(application.organization);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getOrganizations() {
|
getOrganizations() {
|
||||||
OrganizationBackend.getOrganizations("admin")
|
OrganizationBackend.getOrganizations("admin")
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res?.status === "error") {
|
if (res.status === "error") {
|
||||||
this.setState({
|
this.setState({
|
||||||
isAuthorized: false,
|
isAuthorized: false,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
this.setState({
|
||||||
organizations: (res.msg === undefined) ? res : [],
|
organizations: res.data || [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -164,7 +165,7 @@ class ApplicationEditPage extends React.Component {
|
|||||||
CertBackend.getCerts(owner)
|
CertBackend.getCerts(owner)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
certs: (res.msg === undefined) ? res : [],
|
certs: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -184,9 +185,9 @@ class ApplicationEditPage extends React.Component {
|
|||||||
|
|
||||||
getSamlMetadata() {
|
getSamlMetadata() {
|
||||||
ApplicationBackend.getSamlMetadata("admin", this.state.applicationName)
|
ApplicationBackend.getSamlMetadata("admin", this.state.applicationName)
|
||||||
.then((res) => {
|
.then((data) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
samlMetadata: res,
|
samlMetadata: data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -45,7 +45,7 @@ class CertEditPage extends React.Component {
|
|||||||
getCert() {
|
getCert() {
|
||||||
CertBackend.getCert(this.state.owner, this.state.certName)
|
CertBackend.getCert(this.state.owner, this.state.certName)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res === null) {
|
if (res.data === null) {
|
||||||
this.props.history.push("/404");
|
this.props.history.push("/404");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -56,7 +56,7 @@ class CertEditPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
cert: res,
|
cert: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@ class CertEditPage extends React.Component {
|
|||||||
OrganizationBackend.getOrganizations("admin")
|
OrganizationBackend.getOrganizations("admin")
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
organizations: (res.msg === undefined) ? res : [],
|
organizations: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -41,7 +41,7 @@ class ChatEditPage extends React.Component {
|
|||||||
getChat() {
|
getChat() {
|
||||||
ChatBackend.getChat("admin", this.state.chatName)
|
ChatBackend.getChat("admin", this.state.chatName)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res === null) {
|
if (res.data === null) {
|
||||||
this.props.history.push("/404");
|
this.props.history.push("/404");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -51,10 +51,10 @@ class ChatEditPage extends React.Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
chat: res,
|
chat: res.data,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.getUsers(res.organization);
|
this.getUsers(res.data.organization);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ class ChatEditPage extends React.Component {
|
|||||||
OrganizationBackend.getOrganizations("admin")
|
OrganizationBackend.getOrganizations("admin")
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
organizations: (res.msg === undefined) ? res : [],
|
organizations: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ class ChatEditPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
users: res,
|
users: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -79,7 +79,8 @@ class ChatPage extends BaseListPage {
|
|||||||
|
|
||||||
getMessages(chatName) {
|
getMessages(chatName) {
|
||||||
MessageBackend.getChatMessages(chatName)
|
MessageBackend.getChatMessages(chatName)
|
||||||
.then((messages) => {
|
.then((res) => {
|
||||||
|
const messages = res.data;
|
||||||
this.setState({
|
this.setState({
|
||||||
messages: messages,
|
messages: messages,
|
||||||
});
|
});
|
||||||
@@ -229,7 +230,7 @@ class ChatPage extends BaseListPage {
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
<ChatBox messages={this.state.messages} sendMessage={(text) => {this.sendMessage(text);}} account={this.props.account} />
|
<ChatBox messages={this.state.messages || []} sendMessage={(text) => {this.sendMessage(text);}} account={this.props.account} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@@ -79,7 +79,9 @@ class EntryPage extends React.Component {
|
|||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const themeData = res !== null ? Setting.getThemeData(res.organizationObj, res) : Conf.ThemeDefault;
|
|
||||||
|
const application = res.data;
|
||||||
|
const themeData = application !== null ? Setting.getThemeData(application.organizationObj, application) : Conf.ThemeDefault;
|
||||||
this.props.updataThemeData(themeData);
|
this.props.updataThemeData(themeData);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@@ -67,7 +67,7 @@ class GroupEditPage extends React.Component {
|
|||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
this.setState({
|
this.setState({
|
||||||
organizations: res.data,
|
organizations: res.data || [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -55,7 +55,7 @@ class LdapEditPage extends React.Component {
|
|||||||
OrganizationBackend.getOrganizations("admin")
|
OrganizationBackend.getOrganizations("admin")
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
organizations: (res.msg === undefined) ? res : [],
|
organizations: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -46,7 +46,7 @@ class MessageEditPage extends React.Component {
|
|||||||
getMessage() {
|
getMessage() {
|
||||||
MessageBackend.getMessage("admin", this.state.messageName)
|
MessageBackend.getMessage("admin", this.state.messageName)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res === null) {
|
if (res.data === null) {
|
||||||
this.props.history.push("/404");
|
this.props.history.push("/404");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -54,11 +54,11 @@ class MessageEditPage extends React.Component {
|
|||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.setState({
|
|
||||||
message: res,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.getUsers(res.organization);
|
this.setState({
|
||||||
|
message: res.data,
|
||||||
|
});
|
||||||
|
this.getUsers(res.data.organization);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ class MessageEditPage extends React.Component {
|
|||||||
OrganizationBackend.getOrganizations("admin")
|
OrganizationBackend.getOrganizations("admin")
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
organizations: (res.msg === undefined) ? res : [],
|
organizations: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -75,7 +75,7 @@ class MessageEditPage extends React.Component {
|
|||||||
ChatBackend.getChats("admin")
|
ChatBackend.getChats("admin")
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
chats: (res.msg === undefined) ? res : [],
|
chats: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -87,8 +87,9 @@ class MessageEditPage extends React.Component {
|
|||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
users: res,
|
users: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -48,7 +48,7 @@ class ModelEditPage extends React.Component {
|
|||||||
getModel() {
|
getModel() {
|
||||||
ModelBackend.getModel(this.state.organizationName, this.state.modelName)
|
ModelBackend.getModel(this.state.organizationName, this.state.modelName)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res === null) {
|
if (res.data === null) {
|
||||||
this.props.history.push("/404");
|
this.props.history.push("/404");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ class ModelEditPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
model: res,
|
model: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -68,7 +68,7 @@ class ModelEditPage extends React.Component {
|
|||||||
OrganizationBackend.getOrganizations("admin")
|
OrganizationBackend.getOrganizations("admin")
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
organizations: (res.msg === undefined) ? res : [],
|
organizations: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -75,7 +75,7 @@ class OrganizationEditPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
applications: res,
|
applications: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -41,14 +41,14 @@ class PaymentEditPage extends React.Component {
|
|||||||
|
|
||||||
getPayment() {
|
getPayment() {
|
||||||
PaymentBackend.getPayment("admin", this.state.paymentName)
|
PaymentBackend.getPayment("admin", this.state.paymentName)
|
||||||
.then((payment) => {
|
.then((res) => {
|
||||||
if (payment === null) {
|
if (res.data === null) {
|
||||||
this.props.history.push("/404");
|
this.props.history.push("/404");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
payment: payment,
|
payment: res.data,
|
||||||
});
|
});
|
||||||
|
|
||||||
Setting.scrollToDiv("invoice-area");
|
Setting.scrollToDiv("invoice-area");
|
||||||
|
@@ -41,12 +41,12 @@ class PaymentResultPage extends React.Component {
|
|||||||
|
|
||||||
getPayment() {
|
getPayment() {
|
||||||
PaymentBackend.getPayment("admin", this.state.paymentName)
|
PaymentBackend.getPayment("admin", this.state.paymentName)
|
||||||
.then((payment) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
payment: payment,
|
payment: res.data,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (payment.state === "Created") {
|
if (res.data.state === "Created") {
|
||||||
this.setState({timeout: setTimeout(() => this.getPayment(), 1000)});
|
this.setState({timeout: setTimeout(() => this.getPayment(), 1000)});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -50,7 +50,9 @@ class PermissionEditPage extends React.Component {
|
|||||||
getPermission() {
|
getPermission() {
|
||||||
PermissionBackend.getPermission(this.state.organizationName, this.state.permissionName)
|
PermissionBackend.getPermission(this.state.organizationName, this.state.permissionName)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res === null) {
|
const permission = res.data;
|
||||||
|
|
||||||
|
if (permission === null) {
|
||||||
this.props.history.push("/404");
|
this.props.history.push("/404");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -61,14 +63,14 @@ class PermissionEditPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
permission: res,
|
permission: permission,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.getUsers(res.owner);
|
this.getUsers(permission.owner);
|
||||||
this.getRoles(res.owner);
|
this.getRoles(permission.owner);
|
||||||
this.getModels(res.owner);
|
this.getModels(permission.owner);
|
||||||
this.getResources(res.owner);
|
this.getResources(permission.owner);
|
||||||
this.getModel(res.owner, res.model);
|
this.getModel(permission.owner, permission.model);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +78,7 @@ class PermissionEditPage extends React.Component {
|
|||||||
OrganizationBackend.getOrganizations("admin")
|
OrganizationBackend.getOrganizations("admin")
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
organizations: (res.msg === undefined) ? res : [],
|
organizations: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -88,8 +90,9 @@ class PermissionEditPage extends React.Component {
|
|||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
users: res,
|
users: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -101,8 +104,9 @@ class PermissionEditPage extends React.Component {
|
|||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
roles: res,
|
roles: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -114,21 +118,21 @@ class PermissionEditPage extends React.Component {
|
|||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
models: res,
|
models: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getModel(organizationName, modelName) {
|
getModel(organizationName, modelName) {
|
||||||
|
if (modelName === "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
ModelBackend.getModel(organizationName, modelName)
|
ModelBackend.getModel(organizationName, modelName)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === "error") {
|
|
||||||
Setting.showMessage("error", res.msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.setState({
|
this.setState({
|
||||||
model: res,
|
model: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -137,7 +141,7 @@ class PermissionEditPage extends React.Component {
|
|||||||
ApplicationBackend.getApplicationsByOrganization("admin", organizationName)
|
ApplicationBackend.getApplicationsByOrganization("admin", organizationName)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
resources: (res.msg === undefined) ? res : [],
|
resources: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -46,18 +46,18 @@ class PlanEditPage extends React.Component {
|
|||||||
|
|
||||||
getPlan() {
|
getPlan() {
|
||||||
PlanBackend.getPlan(this.state.organizationName, this.state.planName)
|
PlanBackend.getPlan(this.state.organizationName, this.state.planName)
|
||||||
.then((plan) => {
|
.then((res) => {
|
||||||
if (plan === null) {
|
if (res.data === null) {
|
||||||
this.props.history.push("/404");
|
this.props.history.push("/404");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
plan: plan,
|
plan: res.data,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.getUsers(plan.owner);
|
this.getUsers(this.state.organizationName);
|
||||||
this.getRoles(plan.owner);
|
this.getRoles(this.state.organizationName);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,8 +68,9 @@ class PlanEditPage extends React.Component {
|
|||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
roles: res,
|
roles: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -81,8 +82,9 @@ class PlanEditPage extends React.Component {
|
|||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
users: res,
|
users: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -91,7 +93,7 @@ class PlanEditPage extends React.Component {
|
|||||||
OrganizationBackend.getOrganizations("admin")
|
OrganizationBackend.getOrganizations("admin")
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
organizations: (res.msg === undefined) ? res : [],
|
organizations: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -44,13 +44,12 @@ class PricingEditPage extends React.Component {
|
|||||||
this.getPricing();
|
this.getPricing();
|
||||||
this.getOrganizations();
|
this.getOrganizations();
|
||||||
this.getApplicationsByOrganization(this.state.organizationName);
|
this.getApplicationsByOrganization(this.state.organizationName);
|
||||||
this.getUserApplication();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getPricing() {
|
getPricing() {
|
||||||
PricingBackend.getPricing(this.state.organizationName, this.state.pricingName)
|
PricingBackend.getPricing(this.state.organizationName, this.state.pricingName)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res === null) {
|
if (res.data === null) {
|
||||||
this.props.history.push("/404");
|
this.props.history.push("/404");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -61,9 +60,9 @@ class PricingEditPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
pricing: res,
|
pricing: res.data,
|
||||||
});
|
});
|
||||||
this.getPlans(res.owner);
|
this.getPlans(this.state.organizationName);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,8 +73,9 @@ class PricingEditPage extends React.Component {
|
|||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
plans: res,
|
plans: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -84,7 +84,16 @@ class PricingEditPage extends React.Component {
|
|||||||
OrganizationBackend.getOrganizations("admin")
|
OrganizationBackend.getOrganizations("admin")
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
organizations: (res.msg === undefined) ? res : [],
|
organizations: res.data || [],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getApplicationsByOrganization(organizationName) {
|
||||||
|
ApplicationBackend.getApplicationsByOrganization("admin", organizationName)
|
||||||
|
.then((res) => {
|
||||||
|
this.setState({
|
||||||
|
applications: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -107,28 +116,6 @@ class PricingEditPage extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getApplicationsByOrganization(organizationName) {
|
|
||||||
ApplicationBackend.getApplicationsByOrganization("admin", organizationName)
|
|
||||||
.then((res) => {
|
|
||||||
this.setState({
|
|
||||||
applications: (res.msg === undefined) ? res : [],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getUserApplication() {
|
|
||||||
ApplicationBackend.getUserApplication(this.state.organizationName, this.state.userName)
|
|
||||||
.then((res) => {
|
|
||||||
if (res.status === "error") {
|
|
||||||
Setting.showMessage("error", res.msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.setState({
|
|
||||||
application: res,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
renderPricing() {
|
renderPricing() {
|
||||||
return (
|
return (
|
||||||
<Card size="small" title={
|
<Card size="small" title={
|
||||||
|
@@ -48,7 +48,7 @@ class ProductBuyPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
product: res,
|
product: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -46,14 +46,14 @@ class ProductEditPage extends React.Component {
|
|||||||
|
|
||||||
getProduct() {
|
getProduct() {
|
||||||
ProductBackend.getProduct(this.state.organizationName, this.state.productName)
|
ProductBackend.getProduct(this.state.organizationName, this.state.productName)
|
||||||
.then((product) => {
|
.then((res) => {
|
||||||
if (product === null) {
|
if (res.data === null) {
|
||||||
this.props.history.push("/404");
|
this.props.history.push("/404");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
product: product,
|
product: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ class ProductEditPage extends React.Component {
|
|||||||
OrganizationBackend.getOrganizations("admin")
|
OrganizationBackend.getOrganizations("admin")
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
organizations: (res.msg === undefined) ? res : [],
|
organizations: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -50,7 +50,7 @@ class ProviderEditPage extends React.Component {
|
|||||||
getProvider() {
|
getProvider() {
|
||||||
ProviderBackend.getProvider(this.state.owner, this.state.providerName)
|
ProviderBackend.getProvider(this.state.owner, this.state.providerName)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res === null) {
|
if (res.data === null) {
|
||||||
this.props.history.push("/404");
|
this.props.history.push("/404");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@ class ProviderEditPage extends React.Component {
|
|||||||
OrganizationBackend.getOrganizations("admin")
|
OrganizationBackend.getOrganizations("admin")
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
organizations: res.msg === undefined ? res : [],
|
organizations: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -358,6 +358,8 @@ class ProviderEditPage extends React.Component {
|
|||||||
this.updateProviderField("type", "Default");
|
this.updateProviderField("type", "Default");
|
||||||
} else if (value === "AI") {
|
} else if (value === "AI") {
|
||||||
this.updateProviderField("type", "OpenAI API - GPT");
|
this.updateProviderField("type", "OpenAI API - GPT");
|
||||||
|
} else if (value === "Web3") {
|
||||||
|
this.updateProviderField("type", "MetaMask");
|
||||||
}
|
}
|
||||||
})}>
|
})}>
|
||||||
{
|
{
|
||||||
@@ -370,6 +372,7 @@ class ProviderEditPage extends React.Component {
|
|||||||
{id: "SAML", name: "SAML"},
|
{id: "SAML", name: "SAML"},
|
||||||
{id: "SMS", name: "SMS"},
|
{id: "SMS", name: "SMS"},
|
||||||
{id: "Storage", name: "Storage"},
|
{id: "Storage", name: "Storage"},
|
||||||
|
{id: "Web3", name: "Web3"},
|
||||||
]
|
]
|
||||||
.sort((a, b) => a.name.localeCompare(b.name))
|
.sort((a, b) => a.name.localeCompare(b.name))
|
||||||
.map((providerCategory, index) => <Option key={index} value={providerCategory.id}>{providerCategory.name}</Option>)
|
.map((providerCategory, index) => <Option key={index} value={providerCategory.id}>{providerCategory.name}</Option>)
|
||||||
@@ -524,7 +527,7 @@ class ProviderEditPage extends React.Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
this.state.provider.category === "Captcha" && this.state.provider.type === "Default" ? null : (
|
(this.state.provider.category === "Captcha" && this.state.provider.type === "Default") || (this.state.provider.category === "Web3") || (this.state.provider.category === "Storage" && this.state.provider.type === "Local File System") ? null : (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{
|
{
|
||||||
this.state.provider.category === "AI" ? null : (
|
this.state.provider.category === "AI" ? null : (
|
||||||
@@ -613,36 +616,42 @@ class ProviderEditPage extends React.Component {
|
|||||||
}
|
}
|
||||||
{this.state.provider.category === "Storage" ? (
|
{this.state.provider.category === "Storage" ? (
|
||||||
<div>
|
<div>
|
||||||
<Row style={{marginTop: "20px"}} >
|
{["Local File System"].includes(this.state.provider.type) ? null : (
|
||||||
<Col style={{marginTop: "5px"}} span={2}>
|
<Row style={{marginTop: "20px"}} >
|
||||||
{Setting.getLabel(i18next.t("provider:Endpoint"), i18next.t("provider:Region endpoint for Internet"))} :
|
<Col style={{marginTop: "5px"}} span={2}>
|
||||||
</Col>
|
{Setting.getLabel(i18next.t("provider:Endpoint"), i18next.t("provider:Region endpoint for Internet"))} :
|
||||||
<Col span={22} >
|
</Col>
|
||||||
<Input value={this.state.provider.endpoint} onChange={e => {
|
<Col span={22} >
|
||||||
this.updateProviderField("endpoint", e.target.value);
|
<Input value={this.state.provider.endpoint} onChange={e => {
|
||||||
}} />
|
this.updateProviderField("endpoint", e.target.value);
|
||||||
</Col>
|
}} />
|
||||||
</Row>
|
</Col>
|
||||||
<Row style={{marginTop: "20px"}} >
|
</Row>
|
||||||
<Col style={{marginTop: "5px"}} span={2}>
|
)}
|
||||||
{Setting.getLabel(i18next.t("provider:Endpoint (Intranet)"), i18next.t("provider:Region endpoint for Intranet"))} :
|
{["Local File System", "MinIO", "Tencent Cloud COS"].includes(this.state.provider.type) ? null : (
|
||||||
</Col>
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col span={22} >
|
<Col style={{marginTop: "5px"}} span={2}>
|
||||||
<Input value={this.state.provider.intranetEndpoint} onChange={e => {
|
{Setting.getLabel(i18next.t("provider:Endpoint (Intranet)"), i18next.t("provider:Region endpoint for Intranet"))} :
|
||||||
this.updateProviderField("intranetEndpoint", e.target.value);
|
</Col>
|
||||||
}} />
|
<Col span={22} >
|
||||||
</Col>
|
<Input value={this.state.provider.intranetEndpoint} onChange={e => {
|
||||||
</Row>
|
this.updateProviderField("intranetEndpoint", e.target.value);
|
||||||
<Row style={{marginTop: "20px"}} >
|
}} />
|
||||||
<Col style={{marginTop: "5px"}} span={2}>
|
</Col>
|
||||||
{Setting.getLabel(i18next.t("provider:Bucket"), i18next.t("provider:Bucket - Tooltip"))} :
|
</Row>
|
||||||
</Col>
|
)}
|
||||||
<Col span={22} >
|
{["Local File System"].includes(this.state.provider.type) ? null : (
|
||||||
<Input value={this.state.provider.bucket} onChange={e => {
|
<Row style={{marginTop: "20px"}} >
|
||||||
this.updateProviderField("bucket", e.target.value);
|
<Col style={{marginTop: "5px"}} span={2}>
|
||||||
}} />
|
{Setting.getLabel(i18next.t("provider:Bucket"), i18next.t("provider:Bucket - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
<Col span={22} >
|
||||||
|
<Input value={this.state.provider.bucket} onChange={e => {
|
||||||
|
this.updateProviderField("bucket", e.target.value);
|
||||||
|
}} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
)}
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={2}>
|
<Col style={{marginTop: "5px"}} span={2}>
|
||||||
{Setting.getLabel(i18next.t("provider:Path prefix"), i18next.t("provider:Path prefix - Tooltip"))} :
|
{Setting.getLabel(i18next.t("provider:Path prefix"), i18next.t("provider:Path prefix - Tooltip"))} :
|
||||||
@@ -653,17 +662,19 @@ class ProviderEditPage extends React.Component {
|
|||||||
}} />
|
}} />
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
{["MinIO"].includes(this.state.provider.type) ? null : (
|
||||||
<Col style={{marginTop: "5px"}} span={2}>
|
<Row style={{marginTop: "20px"}} >
|
||||||
{Setting.getLabel(i18next.t("provider:Domain"), i18next.t("provider:Domain - Tooltip"))} :
|
<Col style={{marginTop: "5px"}} span={2}>
|
||||||
</Col>
|
{Setting.getLabel(i18next.t("provider:Domain"), i18next.t("provider:Domain - Tooltip"))} :
|
||||||
<Col span={22} >
|
</Col>
|
||||||
<Input value={this.state.provider.domain} onChange={e => {
|
<Col span={22} >
|
||||||
this.updateProviderField("domain", e.target.value);
|
<Input value={this.state.provider.domain} disabled={this.state.provider.type === "Local File System"} onChange={e => {
|
||||||
}} />
|
this.updateProviderField("domain", e.target.value);
|
||||||
</Col>
|
}} />
|
||||||
</Row>
|
</Col>
|
||||||
{["AWS S3", "MinIO", "Tencent Cloud COS"].includes(this.state.provider.type) ? (
|
</Row>
|
||||||
|
)}
|
||||||
|
{["AWS S3", "Tencent Cloud COS"].includes(this.state.provider.type) ? (
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={2}>
|
<Col style={{marginTop: "5px"}} span={2}>
|
||||||
{Setting.getLabel(i18next.t("provider:Region ID"), i18next.t("provider:Region ID - Tooltip"))} :
|
{Setting.getLabel(i18next.t("provider:Region ID"), i18next.t("provider:Region ID - Tooltip"))} :
|
||||||
|
@@ -43,7 +43,7 @@ class RoleEditPage extends React.Component {
|
|||||||
getRole() {
|
getRole() {
|
||||||
RoleBackend.getRole(this.state.organizationName, this.state.roleName)
|
RoleBackend.getRole(this.state.organizationName, this.state.roleName)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res === null) {
|
if (res.data === null) {
|
||||||
this.props.history.push("/404");
|
this.props.history.push("/404");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -53,11 +53,11 @@ class RoleEditPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
role: res,
|
role: res.data,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.getUsers(res.owner);
|
this.getUsers(this.state.organizationName);
|
||||||
this.getRoles(res.owner);
|
this.getRoles(this.state.organizationName);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ class RoleEditPage extends React.Component {
|
|||||||
OrganizationBackend.getOrganizations("admin")
|
OrganizationBackend.getOrganizations("admin")
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
organizations: (res.msg === undefined) ? res : [],
|
organizations: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -77,8 +77,9 @@ class RoleEditPage extends React.Component {
|
|||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
users: res,
|
users: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -90,8 +91,9 @@ class RoleEditPage extends React.Component {
|
|||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
roles: res,
|
roles: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -216,6 +216,12 @@ export const OtherProviderInfo = {
|
|||||||
url: "https://platform.openai.com",
|
url: "https://platform.openai.com",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Web3: {
|
||||||
|
"MetaMask": {
|
||||||
|
logo: `${StaticBaseUrl}/img/social_metamask.svg`,
|
||||||
|
url: "https://metamask.io/",
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function initCountries() {
|
export function initCountries() {
|
||||||
@@ -288,7 +294,7 @@ export function isProviderVisible(providerItem) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (providerItem.provider.category !== "OAuth" && providerItem.provider.category !== "SAML") {
|
if (!["OAuth", "SAML", "Web3"].includes(providerItem.provider.category)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -891,6 +897,10 @@ export function getProviderTypeOptions(category) {
|
|||||||
return ([
|
return ([
|
||||||
{id: "OpenAI API - GPT", name: "OpenAI API - GPT"},
|
{id: "OpenAI API - GPT", name: "OpenAI API - GPT"},
|
||||||
]);
|
]);
|
||||||
|
} else if (category === "Web3") {
|
||||||
|
return ([
|
||||||
|
{id: "MetaMask", name: "MetaMask"},
|
||||||
|
]);
|
||||||
} else {
|
} else {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
@@ -47,7 +47,7 @@ class SubscriptionEditPage extends React.Component {
|
|||||||
getSubscription() {
|
getSubscription() {
|
||||||
SubscriptionBackend.getSubscription(this.state.organizationName, this.state.subscriptionName)
|
SubscriptionBackend.getSubscription(this.state.organizationName, this.state.subscriptionName)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res === null) {
|
if (res.data === null) {
|
||||||
this.props.history.push("/404");
|
this.props.history.push("/404");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -58,11 +58,11 @@ class SubscriptionEditPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
subscription: res,
|
subscription: res.data,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.getUsers(res.owner);
|
this.getUsers(this.state.organizationName);
|
||||||
this.getPlanes(res.owner);
|
this.getPlanes(this.state.organizationName);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ class SubscriptionEditPage extends React.Component {
|
|||||||
PlanBackend.getPlans(organizationName)
|
PlanBackend.getPlans(organizationName)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
planes: res,
|
planes: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -82,8 +82,9 @@ class SubscriptionEditPage extends React.Component {
|
|||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
users: res,
|
users: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -92,7 +93,7 @@ class SubscriptionEditPage extends React.Component {
|
|||||||
OrganizationBackend.getOrganizations("admin")
|
OrganizationBackend.getOrganizations("admin")
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
organizations: (res.msg === undefined) ? res : [],
|
organizations: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -48,7 +48,7 @@ class SyncerEditPage extends React.Component {
|
|||||||
getSyncer() {
|
getSyncer() {
|
||||||
SyncerBackend.getSyncer("admin", this.state.syncerName)
|
SyncerBackend.getSyncer("admin", this.state.syncerName)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res === null) {
|
if (res.data === null) {
|
||||||
this.props.history.push("/404");
|
this.props.history.push("/404");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ class SyncerEditPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
syncer: res,
|
syncer: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -68,7 +68,7 @@ class SyncerEditPage extends React.Component {
|
|||||||
OrganizationBackend.getOrganizations("admin")
|
OrganizationBackend.getOrganizations("admin")
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
organizations: (res.msg === undefined) ? res : [],
|
organizations: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -36,7 +36,7 @@ class TokenEditPage extends React.Component {
|
|||||||
getToken() {
|
getToken() {
|
||||||
TokenBackend.getToken("admin", this.state.tokenName)
|
TokenBackend.getToken("admin", this.state.tokenName)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res === null) {
|
if (res.data === null) {
|
||||||
this.props.history.push("/404");
|
this.props.history.push("/404");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -47,7 +47,7 @@ class TokenEditPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
token: res,
|
token: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -36,6 +36,7 @@ import PopconfirmModal from "./common/modal/PopconfirmModal";
|
|||||||
import {DeleteMfa} from "./backend/MfaBackend";
|
import {DeleteMfa} from "./backend/MfaBackend";
|
||||||
import {CheckCircleOutlined, HolderOutlined, UsergroupAddOutlined} from "@ant-design/icons";
|
import {CheckCircleOutlined, HolderOutlined, UsergroupAddOutlined} from "@ant-design/icons";
|
||||||
import * as MfaBackend from "./backend/MfaBackend";
|
import * as MfaBackend from "./backend/MfaBackend";
|
||||||
|
import AccountAvatar from "./account/AccountAvatar";
|
||||||
|
|
||||||
const {Option} = Select;
|
const {Option} = Select;
|
||||||
|
|
||||||
@@ -74,19 +75,20 @@ class UserEditPage extends React.Component {
|
|||||||
|
|
||||||
getUser() {
|
getUser() {
|
||||||
UserBackend.getUser(this.state.organizationName, this.state.userName)
|
UserBackend.getUser(this.state.organizationName, this.state.userName)
|
||||||
.then((data) => {
|
.then((res) => {
|
||||||
if (data === null) {
|
if (res.data === null) {
|
||||||
this.props.history.push("/404");
|
this.props.history.push("/404");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.status === null || data.status !== "error") {
|
if (res.status === "error") {
|
||||||
this.setState({
|
Setting.showMessage("error", res.msg);
|
||||||
user: data,
|
return;
|
||||||
multiFactorAuths: data?.multiFactorAuths ?? [],
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
|
user: res.data,
|
||||||
|
multiFactorAuths: res.data?.multiFactorAuths ?? [],
|
||||||
loading: false,
|
loading: false,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -107,7 +109,7 @@ class UserEditPage extends React.Component {
|
|||||||
OrganizationBackend.getOrganizations("admin")
|
OrganizationBackend.getOrganizations("admin")
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
organizations: (res.msg === undefined) ? res : [],
|
organizations: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -116,7 +118,7 @@ class UserEditPage extends React.Component {
|
|||||||
ApplicationBackend.getApplicationsByOrganization("admin", organizationName)
|
ApplicationBackend.getApplicationsByOrganization("admin", organizationName)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
applications: (res.msg === undefined) ? res : [],
|
applications: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -128,12 +130,10 @@ class UserEditPage extends React.Component {
|
|||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.setState({
|
|
||||||
application: res,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
isGroupsVisible: res.organizationObj.accountItems?.some((item) => item.name === "Groups" && item.visible),
|
application: res.data,
|
||||||
|
isGroupsVisible: res.data?.organizationObj.accountItems?.some((item) => item.name === "Groups" && item.visible),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -791,10 +791,23 @@ class UserEditPage extends React.Component {
|
|||||||
{
|
{
|
||||||
(this.state.application === null || this.state.user === null) ? null : (
|
(this.state.application === null || this.state.user === null) ? null : (
|
||||||
this.state.application?.providers.filter(providerItem => Setting.isProviderVisible(providerItem)).map((providerItem) =>
|
this.state.application?.providers.filter(providerItem => Setting.isProviderVisible(providerItem)).map((providerItem) =>
|
||||||
(providerItem.provider.category === "OAuth") ? (
|
(providerItem.provider.category === "OAuth" || providerItem.provider.category === "Web3") ? (
|
||||||
<OAuthWidget key={providerItem.name} labelSpan={(Setting.isMobile()) ? 10 : 3} user={this.state.user} application={this.state.application} providerItem={providerItem} account={this.props.account} onUnlinked={() => {return this.unlinked();}} />
|
<OAuthWidget
|
||||||
|
key={providerItem.name}
|
||||||
|
labelSpan={(Setting.isMobile()) ? 10 : 3}
|
||||||
|
user={this.state.user}
|
||||||
|
application={this.state.application}
|
||||||
|
providerItem={providerItem}
|
||||||
|
account={this.props.account}
|
||||||
|
onUnlinked={() => {return this.unlinked();}} />
|
||||||
) : (
|
) : (
|
||||||
<SamlWidget key={providerItem.name} labelSpan={(Setting.isMobile()) ? 10 : 3} user={this.state.user} application={this.state.application} providerItem={providerItem} onUnlinked={() => {return this.unlinked();}} />
|
<SamlWidget
|
||||||
|
key={providerItem.name}
|
||||||
|
labelSpan={(Setting.isMobile()) ? 10 : 3}
|
||||||
|
user={this.state.user}
|
||||||
|
application={this.state.application}
|
||||||
|
providerItem={providerItem}
|
||||||
|
onUnlinked={() => {return this.unlinked();}} />
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -971,7 +984,7 @@ class UserEditPage extends React.Component {
|
|||||||
{
|
{
|
||||||
imgUrl ?
|
imgUrl ?
|
||||||
<a target="_blank" rel="noreferrer" href={imgUrl} style={{marginBottom: "10px"}}>
|
<a target="_blank" rel="noreferrer" href={imgUrl} style={{marginBottom: "10px"}}>
|
||||||
<img src={imgUrl} alt={imgUrl} height={90} style={{marginBottom: "20px"}} />
|
<AccountAvatar src={imgUrl} alt={imgUrl} size={90} style={{marginBottom: "20px"}} />
|
||||||
</a>
|
</a>
|
||||||
:
|
:
|
||||||
<Col style={{height: "78%", border: "1px dotted grey", borderRadius: 3, marginBottom: 5}}>
|
<Col style={{height: "78%", border: "1px dotted grey", borderRadius: 3, marginBottom: 5}}>
|
||||||
|
@@ -23,6 +23,7 @@ import * as UserBackend from "./backend/UserBackend";
|
|||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import BaseListPage from "./BaseListPage";
|
import BaseListPage from "./BaseListPage";
|
||||||
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||||
|
import AccountAvatar from "./account/AccountAvatar";
|
||||||
|
|
||||||
class UserListPage extends BaseListPage {
|
class UserListPage extends BaseListPage {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -270,7 +271,7 @@ class UserListPage extends BaseListPage {
|
|||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
return (
|
return (
|
||||||
<a target="_blank" rel="noreferrer" href={text}>
|
<a target="_blank" rel="noreferrer" href={text}>
|
||||||
<img referrerPolicy="no-referrer" src={text} alt={text} width={50} />
|
<AccountAvatar referrerPolicy="no-referrer" src={text} alt={text} size={50} />
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@@ -122,14 +122,14 @@ class WebhookEditPage extends React.Component {
|
|||||||
|
|
||||||
getWebhook() {
|
getWebhook() {
|
||||||
WebhookBackend.getWebhook("admin", this.state.webhookName)
|
WebhookBackend.getWebhook("admin", this.state.webhookName)
|
||||||
.then((webhook) => {
|
.then((res) => {
|
||||||
if (webhook === null) {
|
if (res.data === null) {
|
||||||
this.props.history.push("/404");
|
this.props.history.push("/404");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
webhook: webhook,
|
webhook: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -138,7 +138,7 @@ class WebhookEditPage extends React.Component {
|
|||||||
OrganizationBackend.getOrganizations("admin")
|
OrganizationBackend.getOrganizations("admin")
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
organizations: (res.msg === undefined) ? res : [],
|
organizations: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
36
web/src/account/AccountAvatar.js
Normal file
36
web/src/account/AccountAvatar.js
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
// 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 React from "react";
|
||||||
|
import {MetaMaskAvatar} from "react-metamask-avatar";
|
||||||
|
|
||||||
|
class AccountAvatar extends React.Component {
|
||||||
|
render() {
|
||||||
|
const {src, size} = this.props;
|
||||||
|
// The avatar for Metamask account is directly generated by an algorithm based on the address
|
||||||
|
// src = "metamask:0xC304b2cC0Be8E9ce10fF3Afd34820Ed306A23600";
|
||||||
|
const matchMetaMask = src.match(/^metamask:(\w+)$/);
|
||||||
|
if (matchMetaMask) {
|
||||||
|
const address = matchMetaMask[1];
|
||||||
|
return (
|
||||||
|
<MetaMaskAvatar address={address} size={size} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<img width={size} height={size} src={src} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AccountAvatar;
|
@@ -95,6 +95,12 @@ class AuthCallback extends React.Component {
|
|||||||
if (code === null) {
|
if (code === null) {
|
||||||
code = params.get("authCode");
|
code = params.get("authCode");
|
||||||
}
|
}
|
||||||
|
// The code for Metamask is the JSON-serialized string of Web3AuthToken
|
||||||
|
// Due to the limited length of URLs, we only pass the web3AuthTokenKey
|
||||||
|
if (code === null) {
|
||||||
|
code = params.get("web3AuthTokenKey");
|
||||||
|
code = localStorage.getItem(code);
|
||||||
|
}
|
||||||
// Steam don't use code, so we should use all params as code.
|
// Steam don't use code, so we should use all params as code.
|
||||||
if (isSteam !== null && code === null) {
|
if (isSteam !== null && code === null) {
|
||||||
code = this.props.location.search;
|
code = this.props.location.search;
|
||||||
|
@@ -68,7 +68,7 @@ class ForgetPage extends React.Component {
|
|||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.onUpdateApplication(res);
|
this.onUpdateApplication(res.data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
getApplicationObj() {
|
getApplicationObj() {
|
||||||
|
@@ -170,10 +170,15 @@ class LoginPage extends React.Component {
|
|||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.onUpdateApplication(res);
|
this.onUpdateApplication(res.data);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
OrganizationBackend.getDefaultApplication("admin", this.state.owner)
|
let redirectUri = "";
|
||||||
|
if (this.state.type === "cas") {
|
||||||
|
const casParams = Util.getCasParameters();
|
||||||
|
redirectUri = casParams.service;
|
||||||
|
}
|
||||||
|
OrganizationBackend.getDefaultApplication("admin", this.state.owner, this.state.type, redirectUri)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
const application = res.data;
|
const application = res.data;
|
||||||
@@ -183,9 +188,9 @@ class LoginPage extends React.Component {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.onUpdateApplication(null);
|
this.onUpdateApplication(null);
|
||||||
Setting.showMessage("error", res.msg);
|
this.setState({
|
||||||
|
msg: res.msg,
|
||||||
this.props.history.push("/404");
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -69,7 +69,7 @@ class MfaSetupPage extends React.Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
application: res,
|
application: res.data,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Setting.showMessage("error", i18next.t("mfa:Failed to get application"));
|
Setting.showMessage("error", i18next.t("mfa:Failed to get application"));
|
||||||
|
@@ -63,7 +63,7 @@ class PromptPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
user: res,
|
user: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -80,9 +80,9 @@ class PromptPage extends React.Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onUpdateApplication(res);
|
this.onUpdateApplication(res.data);
|
||||||
this.setState({
|
this.setState({
|
||||||
application: res,
|
application: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -317,6 +317,10 @@ const authInfo = {
|
|||||||
scope: "user:read",
|
scope: "user:read",
|
||||||
endpoint: "https://zoom.us/oauth/authorize",
|
endpoint: "https://zoom.us/oauth/authorize",
|
||||||
},
|
},
|
||||||
|
MetaMask: {
|
||||||
|
scope: "",
|
||||||
|
endpoint: "",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function getProviderUrl(provider) {
|
export function getProviderUrl(provider) {
|
||||||
@@ -459,5 +463,7 @@ export function getAuthUrl(application, provider, method) {
|
|||||||
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&scope=${scope}&state=${state}&grant_options[]=per-user`;
|
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&scope=${scope}&state=${state}&grant_options[]=per-user`;
|
||||||
} else if (provider.type === "Twitter" || provider.type === "Fitbit") {
|
} else if (provider.type === "Twitter" || provider.type === "Fitbit") {
|
||||||
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}&code_challenge=${codeChallenge}&code_challenge_method=S256`;
|
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}&code_challenge=${codeChallenge}&code_challenge_method=S256`;
|
||||||
|
} else if (provider.type === "MetaMask") {
|
||||||
|
return `${redirectUri}?state=${state}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,6 +17,7 @@ import i18next from "i18next";
|
|||||||
import * as Provider from "./Provider";
|
import * as Provider from "./Provider";
|
||||||
import {getProviderLogoURL} from "../Setting";
|
import {getProviderLogoURL} from "../Setting";
|
||||||
import {GithubLoginButton, GoogleLoginButton} from "react-social-login-buttons";
|
import {GithubLoginButton, GoogleLoginButton} from "react-social-login-buttons";
|
||||||
|
import {authViaMetaMask} from "./Web3Auth";
|
||||||
import QqLoginButton from "./QqLoginButton";
|
import QqLoginButton from "./QqLoginButton";
|
||||||
import FacebookLoginButton from "./FacebookLoginButton";
|
import FacebookLoginButton from "./FacebookLoginButton";
|
||||||
import WeiboLoginButton from "./WeiboLoginButton";
|
import WeiboLoginButton from "./WeiboLoginButton";
|
||||||
@@ -117,6 +118,12 @@ function goToSamlUrl(provider, location) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function goToWeb3Url(application, provider, method) {
|
||||||
|
if (provider.type === "MetaMask") {
|
||||||
|
authViaMetaMask(application, provider, method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function renderProviderLogo(provider, application, width, margin, size, location) {
|
export function renderProviderLogo(provider, application, width, margin, size, location) {
|
||||||
if (size === "small") {
|
if (size === "small") {
|
||||||
if (provider.category === "OAuth") {
|
if (provider.category === "OAuth") {
|
||||||
@@ -153,6 +160,12 @@ export function renderProviderLogo(provider, application, width, margin, size, l
|
|||||||
<img width={width} height={width} src={getProviderLogoURL(provider)} alt={provider.displayName} style={{margin: margin}} />
|
<img width={width} height={width} src={getProviderLogoURL(provider)} alt={provider.displayName} style={{margin: margin}} />
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
|
} else if (provider.category === "Web3") {
|
||||||
|
return (
|
||||||
|
<a key={provider.displayName} onClick={() => goToWeb3Url(application, provider, "signup")}>
|
||||||
|
<img width={width} height={width} src={getProviderLogoURL(provider)} alt={provider.displayName} style={{margin: margin}} />
|
||||||
|
</a>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else if (provider.type === "Custom") {
|
} else if (provider.type === "Custom") {
|
||||||
// style definition
|
// style definition
|
||||||
@@ -192,6 +205,16 @@ export function renderProviderLogo(provider, application, width, margin, size, l
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
} else if (provider.category === "Web3") {
|
||||||
|
return (
|
||||||
|
<div key={provider.displayName} style={{marginBottom: "10px"}}>
|
||||||
|
<a onClick={() => goToWeb3Url(application, provider, "signup")}>
|
||||||
|
{
|
||||||
|
getSigninButton(provider)
|
||||||
|
}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<div key={provider.displayName} style={{marginBottom: "10px"}}>
|
<div key={provider.displayName} style={{marginBottom: "10px"}}>
|
||||||
|
@@ -48,9 +48,10 @@ class ResultPage extends React.Component {
|
|||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.onUpdateApplication(res);
|
|
||||||
|
this.onUpdateApplication(res.data);
|
||||||
this.setState({
|
this.setState({
|
||||||
application: res,
|
application: res.data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -114,7 +114,7 @@ class SignupPage extends React.Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onUpdateApplication(res);
|
this.onUpdateApplication(res.data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
149
web/src/auth/Web3Auth.js
Normal file
149
web/src/auth/Web3Auth.js
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
// // 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 {goToLink, showMessage} from "../Setting";
|
||||||
|
import i18next from "i18next";
|
||||||
|
import {v4 as uuidv4} from "uuid";
|
||||||
|
import {SignTypedDataVersion, recoverTypedSignature} from "@metamask/eth-sig-util";
|
||||||
|
import {getAuthUrl} from "./Provider";
|
||||||
|
import {Buffer} from "buffer";
|
||||||
|
// import {toChecksumAddress} from "ethereumjs-util";
|
||||||
|
global.Buffer = Buffer;
|
||||||
|
|
||||||
|
export function generateNonce() {
|
||||||
|
const nonce = uuidv4();
|
||||||
|
return nonce;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getWeb3AuthTokenKey(address) {
|
||||||
|
return `Web3AuthToken_${address}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setWeb3AuthToken(token) {
|
||||||
|
const key = getWeb3AuthTokenKey(token.address);
|
||||||
|
localStorage.setItem(key, JSON.stringify(token));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getWeb3AuthToken(address) {
|
||||||
|
const key = getWeb3AuthTokenKey(address);
|
||||||
|
return JSON.parse(localStorage.getItem(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function delWeb3AuthToken(address) {
|
||||||
|
const key = getWeb3AuthTokenKey(address);
|
||||||
|
localStorage.removeItem(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function clearWeb3AuthToken() {
|
||||||
|
const keys = Object.keys(localStorage);
|
||||||
|
keys.forEach(key => {
|
||||||
|
if (key.startsWith("Web3AuthToken_")) {
|
||||||
|
localStorage.removeItem(key);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function detectMetaMaskPlugin() {
|
||||||
|
// check if ethereum extension MetaMask is installed
|
||||||
|
return window.ethereum && window.ethereum.isMetaMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function requestEthereumAccount() {
|
||||||
|
const method = "eth_requestAccounts";
|
||||||
|
const selectedAccount = window.ethereum.request({method})
|
||||||
|
.then((accounts) => {
|
||||||
|
return accounts[0];
|
||||||
|
});
|
||||||
|
return selectedAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function signEthereumTypedData(from, nonce) {
|
||||||
|
// https://docs.metamask.io/wallet/how-to/sign-data/
|
||||||
|
const date = new Date();
|
||||||
|
const typedData = JSON.stringify({
|
||||||
|
domain: {
|
||||||
|
chainId: window.ethereum.chainId,
|
||||||
|
name: "Casdoor",
|
||||||
|
version: "1",
|
||||||
|
},
|
||||||
|
message: {
|
||||||
|
prompt: "In order to authenticate to this website, sign this request and your public address will be sent to the server in a verifiable way.",
|
||||||
|
nonce: nonce,
|
||||||
|
createAt: `${date.toLocaleString()}`,
|
||||||
|
},
|
||||||
|
primaryType: "AuthRequest",
|
||||||
|
types: {
|
||||||
|
EIP712Domain: [
|
||||||
|
{name: "name", type: "string"},
|
||||||
|
{name: "version", type: "string"},
|
||||||
|
{name: "chainId", type: "uint256"},
|
||||||
|
],
|
||||||
|
AuthRequest: [
|
||||||
|
{name: "prompt", type: "string"},
|
||||||
|
{name: "nonce", type: "string"},
|
||||||
|
{name: "createAt", type: "string"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const method = "eth_signTypedData_v4";
|
||||||
|
const params = [from, typedData];
|
||||||
|
|
||||||
|
return window.ethereum.request({method, params})
|
||||||
|
.then((sign) => {
|
||||||
|
return {
|
||||||
|
address: from,
|
||||||
|
createAt: Math.floor(date.getTime() / 1000),
|
||||||
|
typedData: typedData,
|
||||||
|
signature: sign,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function checkEthereumSignedTypedData(token) {
|
||||||
|
if (token === undefined || token === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (token.address && token.typedData && token.signature) {
|
||||||
|
const recoveredAddr = recoverTypedSignature({
|
||||||
|
data: JSON.parse(token.typedData),
|
||||||
|
signature: token.signature,
|
||||||
|
version: SignTypedDataVersion.V4,
|
||||||
|
});
|
||||||
|
// const recoveredAddr = token.address;
|
||||||
|
return recoveredAddr === token.address;
|
||||||
|
// return toChecksumAddress(recoveredAddr) === toChecksumAddress(token.address);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function authViaMetaMask(application, provider, method) {
|
||||||
|
if (!detectMetaMaskPlugin()) {
|
||||||
|
showMessage("error", `${i18next.t("login:MetaMask plugin not detected")}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const account = await requestEthereumAccount();
|
||||||
|
let token = getWeb3AuthToken(account);
|
||||||
|
if (!checkEthereumSignedTypedData(token)) {
|
||||||
|
const nonce = generateNonce();
|
||||||
|
token = await signEthereumTypedData(account, nonce);
|
||||||
|
setWeb3AuthToken(token);
|
||||||
|
}
|
||||||
|
const redirectUri = `${getAuthUrl(application, provider, method)}&web3AuthTokenKey=${getWeb3AuthTokenKey(account)}`;
|
||||||
|
goToLink(redirectUri);
|
||||||
|
} catch (err) {
|
||||||
|
showMessage("error", `${i18next.t("login:Failed to obtain MetaMask authorization")}: ${err.message}`);
|
||||||
|
}
|
||||||
|
}
|
@@ -70,8 +70,8 @@ export function deleteOrganization(organization) {
|
|||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDefaultApplication(owner, name) {
|
export function getDefaultApplication(owner, name, type = "", redirectUri = "") {
|
||||||
return fetch(`${Setting.ServerUrl}/api/get-default-application?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-default-application?id=${owner}/${encodeURIComponent(name)}&type=${type}&redirectUri=${redirectUri}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
headers: {
|
headers: {
|
||||||
|
@@ -36,7 +36,7 @@ class HomePage extends React.Component {
|
|||||||
ApplicationBackend.getApplicationsByOrganization("admin", organizationName)
|
ApplicationBackend.getApplicationsByOrganization("admin", organizationName)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
applications: (res.msg === undefined) ? res : [],
|
applications: res.data || [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,9 @@ import * as UserBackend from "../backend/UserBackend";
|
|||||||
import * as Setting from "../Setting";
|
import * as Setting from "../Setting";
|
||||||
import * as Provider from "../auth/Provider";
|
import * as Provider from "../auth/Provider";
|
||||||
import * as AuthBackend from "../auth/AuthBackend";
|
import * as AuthBackend from "../auth/AuthBackend";
|
||||||
|
import {goToWeb3Url} from "../auth/ProviderButton";
|
||||||
|
import {delWeb3AuthToken} from "../auth/Web3Auth";
|
||||||
|
import AccountAvatar from "../account/AccountAvatar";
|
||||||
|
|
||||||
class OAuthWidget extends React.Component {
|
class OAuthWidget extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -88,12 +91,15 @@ class OAuthWidget extends React.Component {
|
|||||||
return user.properties[key];
|
return user.properties[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
unlinkUser(providerType) {
|
unlinkUser(providerType, linkedValue) {
|
||||||
const body = {
|
const body = {
|
||||||
providerType: providerType,
|
providerType: providerType,
|
||||||
// should add the unlink user's info, cause the user may not be logged in, but a admin want to unlink the user.
|
// should add the unlink user's info, cause the user may not be logged in, but a admin want to unlink the user.
|
||||||
user: this.props.user,
|
user: this.props.user,
|
||||||
};
|
};
|
||||||
|
if (providerType === "MetaMask") {
|
||||||
|
delWeb3AuthToken(linkedValue);
|
||||||
|
}
|
||||||
AuthBackend.unlink(body)
|
AuthBackend.unlink(body)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
@@ -151,7 +157,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} referrerPolicy="no-referrer" />
|
<AccountAvatar style={{marginRight: "10px"}} size={30} src={avatarUrl} alt={name} referrerPolicy="no-referrer" />
|
||||||
<span style={{width: this.props.labelSpan === 3 ? "300px" : "200px", display: (Setting.isMobile()) ? "inline" : "inline-block"}}>
|
<span style={{width: this.props.labelSpan === 3 ? "300px" : "200px", display: (Setting.isMobile()) ? "inline" : "inline-block"}}>
|
||||||
{
|
{
|
||||||
linkedValue === "" ? (
|
linkedValue === "" ? (
|
||||||
@@ -169,11 +175,15 @@ class OAuthWidget extends React.Component {
|
|||||||
</span>
|
</span>
|
||||||
{
|
{
|
||||||
linkedValue === "" ? (
|
linkedValue === "" ? (
|
||||||
<a key={provider.displayName} href={user.id !== account.id ? null : Provider.getAuthUrl(application, provider, "link")}>
|
provider.category === "Web3" ? (
|
||||||
<Button style={{marginLeft: "20px", width: linkButtonWidth}} type="primary" disabled={user.id !== account.id}>{i18next.t("user:Link")}</Button>
|
<Button style={{marginLeft: "20px", width: linkButtonWidth}} type="primary" disabled={user.id !== account.id} onClick={() => goToWeb3Url(application, provider, "link")}>{i18next.t("user:Link")}</Button>
|
||||||
</a>
|
) : (
|
||||||
|
<a key={provider.displayName} href={user.id !== account.id ? null : Provider.getAuthUrl(application, provider, "link")}>
|
||||||
|
<Button style={{marginLeft: "20px", width: linkButtonWidth}} type="primary" disabled={user.id !== account.id}>{i18next.t("user:Link")}</Button>
|
||||||
|
</a>
|
||||||
|
)
|
||||||
) : (
|
) : (
|
||||||
<Button disabled={!providerItem.canUnlink && !account.isGlobalAdmin} style={{marginLeft: "20px", width: linkButtonWidth}} onClick={() => this.unlinkUser(provider.type)}>{i18next.t("user:Unlink")}</Button>
|
<Button disabled={!providerItem.canUnlink && !account.isGlobalAdmin} style={{marginLeft: "20px", width: linkButtonWidth}} onClick={() => this.unlinkUser(provider.type, linkedValue)}>{i18next.t("user:Unlink")}</Button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</Col>
|
</Col>
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
import {Checkbox, Form, Modal} from "antd";
|
import {Checkbox, Form, Modal} from "antd";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import React, {useEffect, useState} from "react";
|
import React, {useEffect, useState} from "react";
|
||||||
|
import * as Setting from "../../Setting";
|
||||||
|
|
||||||
export const AgreementModal = (props) => {
|
export const AgreementModal = (props) => {
|
||||||
const {open, onOk, onCancel, application} = props;
|
const {open, onOk, onCancel, application} = props;
|
||||||
@@ -31,14 +32,16 @@ export const AgreementModal = (props) => {
|
|||||||
<Modal
|
<Modal
|
||||||
title={i18next.t("signup:Terms of Use")}
|
title={i18next.t("signup:Terms of Use")}
|
||||||
open={open}
|
open={open}
|
||||||
width={"55vw"}
|
width={Setting.isMobile() ? "100vw" : "55vw"}
|
||||||
closable={false}
|
closable={false}
|
||||||
okText={i18next.t("signup:Accept")}
|
okText={i18next.t("signup:Accept")}
|
||||||
cancelText={i18next.t("signup:Decline")}
|
cancelText={i18next.t("signup:Decline")}
|
||||||
onOk={onOk}
|
onOk={onOk}
|
||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
|
style={{top: Setting.isMobile() ? "5px" : ""}}
|
||||||
|
maskStyle={{backgroundColor: Setting.isMobile() ? "white" : ""}}
|
||||||
>
|
>
|
||||||
<iframe title={"terms"} style={{border: 0, width: "100%", height: "60vh"}} srcDoc={doc} />
|
<iframe title={"terms"} style={{border: 0, width: "100%", height: Setting.isMobile() ? "80vh" : "60vh"}} srcDoc={doc} />
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -392,9 +392,11 @@
|
|||||||
"Auto sign in": "Automatische Anmeldung",
|
"Auto sign in": "Automatische Anmeldung",
|
||||||
"Continue with": "Weitermachen mit",
|
"Continue with": "Weitermachen mit",
|
||||||
"Email or phone": "E-Mail oder Telefon",
|
"Email or phone": "E-Mail oder Telefon",
|
||||||
|
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||||
"Forgot password?": "Passwort vergessen?",
|
"Forgot password?": "Passwort vergessen?",
|
||||||
"Loading": "Laden",
|
"Loading": "Laden",
|
||||||
"Logging out...": "Ausloggen...",
|
"Logging out...": "Ausloggen...",
|
||||||
|
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||||
"No account?": "Kein Konto?",
|
"No account?": "Kein Konto?",
|
||||||
"Or sign in with another account": "Oder mit einem anderen Konto anmelden",
|
"Or sign in with another account": "Oder mit einem anderen Konto anmelden",
|
||||||
"Please input your Email or Phone!": "Bitte geben Sie Ihre E-Mail oder Telefonnummer ein!",
|
"Please input your Email or Phone!": "Bitte geben Sie Ihre E-Mail oder Telefonnummer ein!",
|
||||||
|
@@ -392,9 +392,11 @@
|
|||||||
"Auto sign in": "Auto sign in",
|
"Auto sign in": "Auto sign in",
|
||||||
"Continue with": "Continue with",
|
"Continue with": "Continue with",
|
||||||
"Email or phone": "Email or phone",
|
"Email or phone": "Email or phone",
|
||||||
|
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||||
"Forgot password?": "Forgot password?",
|
"Forgot password?": "Forgot password?",
|
||||||
"Loading": "Loading",
|
"Loading": "Loading",
|
||||||
"Logging out...": "Logging out...",
|
"Logging out...": "Logging out...",
|
||||||
|
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||||
"No account?": "No account?",
|
"No account?": "No account?",
|
||||||
"Or sign in with another account": "Or sign in with another account",
|
"Or sign in with another account": "Or sign in with another account",
|
||||||
"Please input your Email or Phone!": "Please input your Email or Phone!",
|
"Please input your Email or Phone!": "Please input your Email or Phone!",
|
||||||
|
@@ -392,9 +392,11 @@
|
|||||||
"Auto sign in": "Inicio de sesión automático",
|
"Auto sign in": "Inicio de sesión automático",
|
||||||
"Continue with": "Continúe con",
|
"Continue with": "Continúe con",
|
||||||
"Email or phone": "Correo electrónico o teléfono",
|
"Email or phone": "Correo electrónico o teléfono",
|
||||||
|
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||||
"Forgot password?": "¿Olvidaste tu contraseña?",
|
"Forgot password?": "¿Olvidaste tu contraseña?",
|
||||||
"Loading": "Cargando",
|
"Loading": "Cargando",
|
||||||
"Logging out...": "Cerrando sesión...",
|
"Logging out...": "Cerrando sesión...",
|
||||||
|
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||||
"No account?": "¿No tienes cuenta?",
|
"No account?": "¿No tienes cuenta?",
|
||||||
"Or sign in with another account": "O inicia sesión con otra cuenta",
|
"Or sign in with another account": "O inicia sesión con otra cuenta",
|
||||||
"Please input your Email or Phone!": "¡Por favor introduzca su correo electrónico o teléfono!",
|
"Please input your Email or Phone!": "¡Por favor introduzca su correo electrónico o teléfono!",
|
||||||
|
@@ -392,9 +392,11 @@
|
|||||||
"Auto sign in": "Connexion automatique",
|
"Auto sign in": "Connexion automatique",
|
||||||
"Continue with": "Continuer avec",
|
"Continue with": "Continuer avec",
|
||||||
"Email or phone": "Email ou téléphone",
|
"Email or phone": "Email ou téléphone",
|
||||||
|
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||||
"Forgot password?": "Mot de passe oublié ?",
|
"Forgot password?": "Mot de passe oublié ?",
|
||||||
"Loading": "Chargement",
|
"Loading": "Chargement",
|
||||||
"Logging out...": "Déconnexion...",
|
"Logging out...": "Déconnexion...",
|
||||||
|
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||||
"No account?": "Aucun compte ?",
|
"No account?": "Aucun compte ?",
|
||||||
"Or sign in with another account": "Ou connectez-vous avec un autre compte",
|
"Or sign in with another account": "Ou connectez-vous avec un autre compte",
|
||||||
"Please input your Email or Phone!": "S'il vous plaît, entrez votre adresse e-mail ou votre numéro de téléphone !",
|
"Please input your Email or Phone!": "S'il vous plaît, entrez votre adresse e-mail ou votre numéro de téléphone !",
|
||||||
|
@@ -392,9 +392,11 @@
|
|||||||
"Auto sign in": "Masuk otomatis",
|
"Auto sign in": "Masuk otomatis",
|
||||||
"Continue with": "Lanjutkan dengan",
|
"Continue with": "Lanjutkan dengan",
|
||||||
"Email or phone": "Email atau telepon",
|
"Email or phone": "Email atau telepon",
|
||||||
|
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||||
"Forgot password?": "Lupa kata sandi?",
|
"Forgot password?": "Lupa kata sandi?",
|
||||||
"Loading": "Memuat",
|
"Loading": "Memuat",
|
||||||
"Logging out...": "Keluar...",
|
"Logging out...": "Keluar...",
|
||||||
|
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||||
"No account?": "Tidak memiliki akun?",
|
"No account?": "Tidak memiliki akun?",
|
||||||
"Or sign in with another account": "Atau masuk dengan akun lain",
|
"Or sign in with another account": "Atau masuk dengan akun lain",
|
||||||
"Please input your Email or Phone!": "Silahkan masukkan email atau nomor telepon Anda!",
|
"Please input your Email or Phone!": "Silahkan masukkan email atau nomor telepon Anda!",
|
||||||
|
@@ -392,9 +392,11 @@
|
|||||||
"Auto sign in": "自動サインイン",
|
"Auto sign in": "自動サインイン",
|
||||||
"Continue with": "続ける",
|
"Continue with": "続ける",
|
||||||
"Email or phone": "メールまたは電話",
|
"Email or phone": "メールまたは電話",
|
||||||
|
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||||
"Forgot password?": "パスワードを忘れましたか?",
|
"Forgot password?": "パスワードを忘れましたか?",
|
||||||
"Loading": "ローディング",
|
"Loading": "ローディング",
|
||||||
"Logging out...": "ログアウト中...",
|
"Logging out...": "ログアウト中...",
|
||||||
|
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||||
"No account?": "アカウントがありませんか?",
|
"No account?": "アカウントがありませんか?",
|
||||||
"Or sign in with another account": "別のアカウントでサインインする",
|
"Or sign in with another account": "別のアカウントでサインインする",
|
||||||
"Please input your Email or Phone!": "あなたのメールアドレスまたは電話番号を入力してください!",
|
"Please input your Email or Phone!": "あなたのメールアドレスまたは電話番号を入力してください!",
|
||||||
|
@@ -392,9 +392,11 @@
|
|||||||
"Auto sign in": "자동 로그인",
|
"Auto sign in": "자동 로그인",
|
||||||
"Continue with": "계속하다",
|
"Continue with": "계속하다",
|
||||||
"Email or phone": "이메일 또는 전화",
|
"Email or phone": "이메일 또는 전화",
|
||||||
|
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||||
"Forgot password?": "비밀번호를 잊으셨나요?",
|
"Forgot password?": "비밀번호를 잊으셨나요?",
|
||||||
"Loading": "로딩 중입니다",
|
"Loading": "로딩 중입니다",
|
||||||
"Logging out...": "로그아웃 중...",
|
"Logging out...": "로그아웃 중...",
|
||||||
|
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||||
"No account?": "계정이 없나요?",
|
"No account?": "계정이 없나요?",
|
||||||
"Or sign in with another account": "다른 계정으로 로그인하세요",
|
"Or sign in with another account": "다른 계정으로 로그인하세요",
|
||||||
"Please input your Email or Phone!": "이메일 또는 전화번호를 입력해주세요!",
|
"Please input your Email or Phone!": "이메일 또는 전화번호를 입력해주세요!",
|
||||||
|
@@ -392,9 +392,11 @@
|
|||||||
"Auto sign in": "Entrar automaticamente",
|
"Auto sign in": "Entrar automaticamente",
|
||||||
"Continue with": "Continuar com",
|
"Continue with": "Continuar com",
|
||||||
"Email or phone": "Email ou telefone",
|
"Email or phone": "Email ou telefone",
|
||||||
|
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||||
"Forgot password?": "Esqueceu a senha?",
|
"Forgot password?": "Esqueceu a senha?",
|
||||||
"Loading": "Carregando",
|
"Loading": "Carregando",
|
||||||
"Logging out...": "Saindo...",
|
"Logging out...": "Saindo...",
|
||||||
|
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||||
"No account?": "Não possui uma conta?",
|
"No account?": "Não possui uma conta?",
|
||||||
"Or sign in with another account": "Ou entre com outra conta",
|
"Or sign in with another account": "Ou entre com outra conta",
|
||||||
"Please input your Email or Phone!": "Por favor, informe seu email ou telefone!",
|
"Please input your Email or Phone!": "Por favor, informe seu email ou telefone!",
|
||||||
|
@@ -392,9 +392,11 @@
|
|||||||
"Auto sign in": "Автоматическая авторизация",
|
"Auto sign in": "Автоматическая авторизация",
|
||||||
"Continue with": "Продолжайте с",
|
"Continue with": "Продолжайте с",
|
||||||
"Email or phone": "Электронная почта или телефон",
|
"Email or phone": "Электронная почта или телефон",
|
||||||
|
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||||
"Forgot password?": "Забыли пароль?",
|
"Forgot password?": "Забыли пароль?",
|
||||||
"Loading": "Загрузка",
|
"Loading": "Загрузка",
|
||||||
"Logging out...": "Выход...",
|
"Logging out...": "Выход...",
|
||||||
|
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||||
"No account?": "Нет аккаунта?",
|
"No account?": "Нет аккаунта?",
|
||||||
"Or sign in with another account": "Или войти с другой учетной записью",
|
"Or sign in with another account": "Или войти с другой учетной записью",
|
||||||
"Please input your Email or Phone!": "Пожалуйста, введите свой адрес электронной почты или номер телефона!",
|
"Please input your Email or Phone!": "Пожалуйста, введите свой адрес электронной почты или номер телефона!",
|
||||||
|
@@ -392,9 +392,11 @@
|
|||||||
"Auto sign in": "Tự động đăng nhập",
|
"Auto sign in": "Tự động đăng nhập",
|
||||||
"Continue with": "Tiếp tục với",
|
"Continue with": "Tiếp tục với",
|
||||||
"Email or phone": "Email hoặc điện thoại",
|
"Email or phone": "Email hoặc điện thoại",
|
||||||
|
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||||
"Forgot password?": "Quên mật khẩu?",
|
"Forgot password?": "Quên mật khẩu?",
|
||||||
"Loading": "Đang tải",
|
"Loading": "Đang tải",
|
||||||
"Logging out...": "Đăng xuất ...",
|
"Logging out...": "Đăng xuất ...",
|
||||||
|
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||||
"No account?": "Không có tài khoản?",
|
"No account?": "Không có tài khoản?",
|
||||||
"Or sign in with another account": "Hoặc đăng nhập bằng tài khoản khác",
|
"Or sign in with another account": "Hoặc đăng nhập bằng tài khoản khác",
|
||||||
"Please input your Email or Phone!": "Vui lòng nhập địa chỉ Email hoặc số điện thoại của bạn!",
|
"Please input your Email or Phone!": "Vui lòng nhập địa chỉ Email hoặc số điện thoại của bạn!",
|
||||||
|
@@ -392,9 +392,11 @@
|
|||||||
"Auto sign in": "下次自动登录",
|
"Auto sign in": "下次自动登录",
|
||||||
"Continue with": "使用以下账号继续",
|
"Continue with": "使用以下账号继续",
|
||||||
"Email or phone": "Email或手机号",
|
"Email or phone": "Email或手机号",
|
||||||
|
"Failed to obtain MetaMask authorization": "获取MetaMask授权失败",
|
||||||
"Forgot password?": "忘记密码?",
|
"Forgot password?": "忘记密码?",
|
||||||
"Loading": "加载中",
|
"Loading": "加载中",
|
||||||
"Logging out...": "正在退出登录...",
|
"Logging out...": "正在退出登录...",
|
||||||
|
"MetaMask plugin not detected": "未检测到MetaMask插件",
|
||||||
"No account?": "没有账号?",
|
"No account?": "没有账号?",
|
||||||
"Or sign in with another account": "或者,登录其他账号",
|
"Or sign in with another account": "或者,登录其他账号",
|
||||||
"Please input your Email or Phone!": "请输入您的Email或手机号!",
|
"Please input your Email or Phone!": "请输入您的Email或手机号!",
|
||||||
@@ -746,6 +748,8 @@
|
|||||||
"Token URL - Tooltip": "自定义OAuth的Token URL",
|
"Token URL - Tooltip": "自定义OAuth的Token URL",
|
||||||
"Type": "类型",
|
"Type": "类型",
|
||||||
"Type - Tooltip": "类型",
|
"Type - Tooltip": "类型",
|
||||||
|
"User mapping": "User mapping",
|
||||||
|
"User mapping - Tooltip": "User mapping - Tooltip",
|
||||||
"UserInfo URL": "UserInfo URL",
|
"UserInfo URL": "UserInfo URL",
|
||||||
"UserInfo URL - Tooltip": "自定义OAuth的UserInfo URL",
|
"UserInfo URL - Tooltip": "自定义OAuth的UserInfo URL",
|
||||||
"admin (Shared)": "admin(共享)"
|
"admin (Shared)": "admin(共享)"
|
||||||
|
@@ -110,7 +110,7 @@ class ProviderTable extends React.Component {
|
|||||||
key: "canSignUp",
|
key: "canSignUp",
|
||||||
width: "120px",
|
width: "120px",
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
if (record.provider?.category !== "OAuth") {
|
if (!["OAuth", "Web3"].includes(record.provider?.category)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ class ProviderTable extends React.Component {
|
|||||||
key: "canSignIn",
|
key: "canSignIn",
|
||||||
width: "120px",
|
width: "120px",
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
if (record.provider?.category !== "OAuth") {
|
if (!["OAuth", "Web3"].includes(record.provider?.category)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ class ProviderTable extends React.Component {
|
|||||||
key: "canUnlink",
|
key: "canUnlink",
|
||||||
width: "120px",
|
width: "120px",
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
if (record.provider?.category !== "OAuth") {
|
if (!["OAuth", "Web3"].includes(record.provider?.category)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,7 +161,7 @@ class ProviderTable extends React.Component {
|
|||||||
key: "prompted",
|
key: "prompted",
|
||||||
width: "120px",
|
width: "120px",
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
if (record.provider?.category !== "OAuth") {
|
if (!["OAuth", "Web3"].includes(record.provider?.category)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
137
web/yarn.lock
137
web/yarn.lock
@@ -173,7 +173,7 @@
|
|||||||
lru-cache "^5.1.1"
|
lru-cache "^5.1.1"
|
||||||
semver "^6.3.0"
|
semver "^6.3.0"
|
||||||
|
|
||||||
"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0", "@babel/helper-create-class-features-plugin@^7.22.5":
|
"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.22.5":
|
||||||
version "7.22.5"
|
version "7.22.5"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.5.tgz#2192a1970ece4685fbff85b48da2c32fcb130b7c"
|
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.5.tgz#2192a1970ece4685fbff85b48da2c32fcb130b7c"
|
||||||
integrity sha512-xkb58MyOYIslxu3gKmVXmjTtUPvBU4odYzbiIQbWwLKIHCsx6UGZGX6F1IznMFVnDdirseUZopzN+ZRt8Xb33Q==
|
integrity sha512-xkb58MyOYIslxu3gKmVXmjTtUPvBU4odYzbiIQbWwLKIHCsx6UGZGX6F1IznMFVnDdirseUZopzN+ZRt8Xb33Q==
|
||||||
@@ -433,16 +433,6 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703"
|
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703"
|
||||||
integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==
|
integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==
|
||||||
|
|
||||||
"@babel/plugin-proposal-private-property-in-object@^7.21.11":
|
|
||||||
version "7.21.11"
|
|
||||||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz#69d597086b6760c4126525cfa154f34631ff272c"
|
|
||||||
integrity sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw==
|
|
||||||
dependencies:
|
|
||||||
"@babel/helper-annotate-as-pure" "^7.18.6"
|
|
||||||
"@babel/helper-create-class-features-plugin" "^7.21.0"
|
|
||||||
"@babel/helper-plugin-utils" "^7.20.2"
|
|
||||||
"@babel/plugin-syntax-private-property-in-object" "^7.14.5"
|
|
||||||
|
|
||||||
"@babel/plugin-proposal-unicode-property-regex@^7.4.4":
|
"@babel/plugin-proposal-unicode-property-regex@^7.4.4":
|
||||||
version "7.18.6"
|
version "7.18.6"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz#af613d2cd5e643643b65cded64207b15c85cb78e"
|
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz#af613d2cd5e643643b65cded64207b15c85cb78e"
|
||||||
@@ -1590,6 +1580,20 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.43.0.tgz#559ca3d9ddbd6bf907ad524320a0d14b85586af0"
|
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.43.0.tgz#559ca3d9ddbd6bf907ad524320a0d14b85586af0"
|
||||||
integrity sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==
|
integrity sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==
|
||||||
|
|
||||||
|
"@ethereumjs/rlp@^4.0.1":
|
||||||
|
version "4.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-4.0.1.tgz#626fabfd9081baab3d0a3074b0c7ecaf674aaa41"
|
||||||
|
integrity sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==
|
||||||
|
|
||||||
|
"@ethereumjs/util@^8.0.6":
|
||||||
|
version "8.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-8.1.0.tgz#299df97fb6b034e0577ce9f94c7d9d1004409ed4"
|
||||||
|
integrity sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==
|
||||||
|
dependencies:
|
||||||
|
"@ethereumjs/rlp" "^4.0.1"
|
||||||
|
ethereum-cryptography "^2.0.0"
|
||||||
|
micro-ftch "^0.3.1"
|
||||||
|
|
||||||
"@humanwhocodes/config-array@^0.10.4":
|
"@humanwhocodes/config-array@^0.10.4":
|
||||||
version "0.10.7"
|
version "0.10.7"
|
||||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.10.7.tgz#6d53769fd0c222767e6452e8ebda825c22e9f0dc"
|
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.10.7.tgz#6d53769fd0c222767e6452e8ebda825c22e9f0dc"
|
||||||
@@ -1931,6 +1935,18 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b"
|
resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b"
|
||||||
integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==
|
integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==
|
||||||
|
|
||||||
|
"@metamask/eth-sig-util@^6.0.0":
|
||||||
|
version "6.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-6.0.0.tgz#083321dc7285a9aa6e066db7c49be6e94c5e03a3"
|
||||||
|
integrity sha512-M0ezVz8lirXG1P6rHPzx+9i4zfhebCgVHE8XQT8VWxy/eUWllHQGcBcE8QmOusC7su55M4CMr9AyMIu0lx452g==
|
||||||
|
dependencies:
|
||||||
|
"@ethereumjs/util" "^8.0.6"
|
||||||
|
bn.js "^4.12.0"
|
||||||
|
ethereum-cryptography "^2.0.0"
|
||||||
|
ethjs-util "^0.1.6"
|
||||||
|
tweetnacl "^1.0.3"
|
||||||
|
tweetnacl-util "^0.15.1"
|
||||||
|
|
||||||
"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1":
|
"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1":
|
||||||
version "5.1.1-v1"
|
version "5.1.1-v1"
|
||||||
resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129"
|
resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129"
|
||||||
@@ -1938,6 +1954,18 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
eslint-scope "5.1.1"
|
eslint-scope "5.1.1"
|
||||||
|
|
||||||
|
"@noble/curves@1.1.0", "@noble/curves@~1.1.0":
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d"
|
||||||
|
integrity sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==
|
||||||
|
dependencies:
|
||||||
|
"@noble/hashes" "1.3.1"
|
||||||
|
|
||||||
|
"@noble/hashes@1.3.1", "@noble/hashes@~1.3.0", "@noble/hashes@~1.3.1":
|
||||||
|
version "1.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9"
|
||||||
|
integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==
|
||||||
|
|
||||||
"@nodelib/fs.scandir@2.1.5":
|
"@nodelib/fs.scandir@2.1.5":
|
||||||
version "2.1.5"
|
version "2.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
|
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
|
||||||
@@ -2094,6 +2122,28 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.3.2.tgz#31b9c510d8cada9683549e1dbb4284cca5001faf"
|
resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.3.2.tgz#31b9c510d8cada9683549e1dbb4284cca5001faf"
|
||||||
integrity sha512-V+MvGwaHH03hYhY+k6Ef/xKd6RYlc4q8WBx+2ANmipHJcKuktNcI/NgEsJgdSUF6Lw32njT6OnrRsKYCdgHjYw==
|
integrity sha512-V+MvGwaHH03hYhY+k6Ef/xKd6RYlc4q8WBx+2ANmipHJcKuktNcI/NgEsJgdSUF6Lw32njT6OnrRsKYCdgHjYw==
|
||||||
|
|
||||||
|
"@scure/base@~1.1.0":
|
||||||
|
version "1.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938"
|
||||||
|
integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==
|
||||||
|
|
||||||
|
"@scure/bip32@1.3.1":
|
||||||
|
version "1.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.1.tgz#7248aea723667f98160f593d621c47e208ccbb10"
|
||||||
|
integrity sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==
|
||||||
|
dependencies:
|
||||||
|
"@noble/curves" "~1.1.0"
|
||||||
|
"@noble/hashes" "~1.3.1"
|
||||||
|
"@scure/base" "~1.1.0"
|
||||||
|
|
||||||
|
"@scure/bip39@1.2.1":
|
||||||
|
version "1.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.1.tgz#5cee8978656b272a917b7871c981e0541ad6ac2a"
|
||||||
|
integrity sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==
|
||||||
|
dependencies:
|
||||||
|
"@noble/hashes" "~1.3.0"
|
||||||
|
"@scure/base" "~1.1.0"
|
||||||
|
|
||||||
"@sheerun/mutationobserver-shim@^0.3.2":
|
"@sheerun/mutationobserver-shim@^0.3.2":
|
||||||
version "0.3.3"
|
version "0.3.3"
|
||||||
resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz#5405ee8e444ed212db44e79351f0c70a582aae25"
|
resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz#5405ee8e444ed212db44e79351f0c70a582aae25"
|
||||||
@@ -3674,6 +3724,11 @@ bluebird@^3.5.5, bluebird@^3.7.2:
|
|||||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
|
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
|
||||||
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
|
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
|
||||||
|
|
||||||
|
bn.js@^4.12.0:
|
||||||
|
version "4.12.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
|
||||||
|
integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
|
||||||
|
|
||||||
body-parser@1.20.1:
|
body-parser@1.20.1:
|
||||||
version "1.20.1"
|
version "1.20.1"
|
||||||
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668"
|
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668"
|
||||||
@@ -3769,6 +3824,14 @@ buffer@^5.6.0:
|
|||||||
base64-js "^1.3.1"
|
base64-js "^1.3.1"
|
||||||
ieee754 "^1.1.13"
|
ieee754 "^1.1.13"
|
||||||
|
|
||||||
|
buffer@^6.0.3:
|
||||||
|
version "6.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
|
||||||
|
integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
|
||||||
|
dependencies:
|
||||||
|
base64-js "^1.3.1"
|
||||||
|
ieee754 "^1.2.1"
|
||||||
|
|
||||||
builtin-modules@^3.1.0:
|
builtin-modules@^3.1.0:
|
||||||
version "3.3.0"
|
version "3.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6"
|
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6"
|
||||||
@@ -5480,6 +5543,24 @@ etag@~1.8.1:
|
|||||||
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
||||||
integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
|
integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
|
||||||
|
|
||||||
|
ethereum-cryptography@^2.0.0:
|
||||||
|
version "2.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz#18fa7108622e56481157a5cb7c01c0c6a672eb67"
|
||||||
|
integrity sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug==
|
||||||
|
dependencies:
|
||||||
|
"@noble/curves" "1.1.0"
|
||||||
|
"@noble/hashes" "1.3.1"
|
||||||
|
"@scure/bip32" "1.3.1"
|
||||||
|
"@scure/bip39" "1.2.1"
|
||||||
|
|
||||||
|
ethjs-util@^0.1.6:
|
||||||
|
version "0.1.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536"
|
||||||
|
integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==
|
||||||
|
dependencies:
|
||||||
|
is-hex-prefixed "1.0.0"
|
||||||
|
strip-hex-prefix "1.0.0"
|
||||||
|
|
||||||
eventemitter2@6.4.7:
|
eventemitter2@6.4.7:
|
||||||
version "6.4.7"
|
version "6.4.7"
|
||||||
resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.7.tgz#a7f6c4d7abf28a14c1ef3442f21cb306a054271d"
|
resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.7.tgz#a7f6c4d7abf28a14c1ef3442f21cb306a054271d"
|
||||||
@@ -6463,7 +6544,7 @@ identity-obj-proxy@^3.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
harmony-reflect "^1.4.6"
|
harmony-reflect "^1.4.6"
|
||||||
|
|
||||||
ieee754@^1.1.13:
|
ieee754@^1.1.13, ieee754@^1.2.1:
|
||||||
version "1.2.1"
|
version "1.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
||||||
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
||||||
@@ -6668,6 +6749,11 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
is-extglob "^2.1.1"
|
is-extglob "^2.1.1"
|
||||||
|
|
||||||
|
is-hex-prefixed@1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554"
|
||||||
|
integrity sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==
|
||||||
|
|
||||||
is-installed-globally@~0.4.0:
|
is-installed-globally@~0.4.0:
|
||||||
version "0.4.0"
|
version "0.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520"
|
resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520"
|
||||||
@@ -7978,6 +8064,11 @@ methods@~1.1.2:
|
|||||||
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
|
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
|
||||||
integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==
|
integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==
|
||||||
|
|
||||||
|
micro-ftch@^0.3.1:
|
||||||
|
version "0.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/micro-ftch/-/micro-ftch-0.3.1.tgz#6cb83388de4c1f279a034fb0cf96dfc050853c5f"
|
||||||
|
integrity sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==
|
||||||
|
|
||||||
micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5:
|
micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5:
|
||||||
version "4.0.5"
|
version "4.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
|
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
|
||||||
@@ -10150,6 +10241,11 @@ react-is@^18.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
|
||||||
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
|
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
|
||||||
|
|
||||||
|
react-metamask-avatar@^1.2.1:
|
||||||
|
version "1.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-metamask-avatar/-/react-metamask-avatar-1.2.1.tgz#f0623e00ebc90ec24b8ac91cad3a25f653e7bc25"
|
||||||
|
integrity sha512-EQhaW27PdqGKLxCnDgpCTWnEs1bjba+l5b/ZQc1V/GSWrCznAcrQ2HrcjSPgmuud2rvDChYyrzgRB5sBU33gSw==
|
||||||
|
|
||||||
react-refresh@^0.11.0:
|
react-refresh@^0.11.0:
|
||||||
version "0.11.0"
|
version "0.11.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046"
|
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046"
|
||||||
@@ -11194,6 +11290,13 @@ strip-final-newline@^3.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd"
|
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd"
|
||||||
integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==
|
integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==
|
||||||
|
|
||||||
|
strip-hex-prefix@1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f"
|
||||||
|
integrity sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==
|
||||||
|
dependencies:
|
||||||
|
is-hex-prefixed "1.0.0"
|
||||||
|
|
||||||
strip-indent@^3.0.0:
|
strip-indent@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001"
|
resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001"
|
||||||
@@ -11731,11 +11834,21 @@ tunnel-agent@^0.6.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "^5.0.1"
|
safe-buffer "^5.0.1"
|
||||||
|
|
||||||
|
tweetnacl-util@^0.15.1:
|
||||||
|
version "0.15.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b"
|
||||||
|
integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==
|
||||||
|
|
||||||
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
||||||
version "0.14.5"
|
version "0.14.5"
|
||||||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
||||||
integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==
|
integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==
|
||||||
|
|
||||||
|
tweetnacl@^1.0.3:
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596"
|
||||||
|
integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==
|
||||||
|
|
||||||
type-check@^0.4.0, type-check@~0.4.0:
|
type-check@^0.4.0, type-check@~0.4.0:
|
||||||
version "0.4.0"
|
version "0.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
|
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
|
||||||
|
Reference in New Issue
Block a user