Merge pull request #1847 from LalitDeore/license-1
Fix - branding and licensing issue
This commit is contained in:
+67
-32
@@ -76,6 +76,7 @@ type retStruct struct {
|
|||||||
IntervalSeconds int64 `json:"interval_seconds"`
|
IntervalSeconds int64 `json:"interval_seconds"`
|
||||||
Reason string `json:"reason"`
|
Reason string `json:"reason"`
|
||||||
Subscriptions []shuffle.PaymentSubscription `json:"subscriptions"`
|
Subscriptions []shuffle.PaymentSubscription `json:"subscriptions"`
|
||||||
|
Licensed bool `json:"licensed"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Contact struct {
|
type Contact struct {
|
||||||
@@ -951,42 +952,62 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) {
|
|||||||
return childOrgs[i].Created < childOrgs[j].Created
|
return childOrgs[i].Created < childOrgs[j].Created
|
||||||
})
|
})
|
||||||
|
|
||||||
|
parentOrg := &shuffle.Org{}
|
||||||
|
if len(org.CreatorOrg) > 0 {
|
||||||
|
parentOrg, err = shuffle.GetOrg(ctx, org.CreatorOrg)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERROR] Failed to get parent org during getinfo: %s", err)
|
||||||
|
parentOrg = &shuffle.Org{}
|
||||||
|
}
|
||||||
|
licenseOrg := shuffle.HandleCheckLicense(ctx, *parentOrg)
|
||||||
|
parentOrg = &licenseOrg
|
||||||
|
}
|
||||||
|
|
||||||
|
limit := 3
|
||||||
|
|
||||||
|
if parentOrg.Licensed && parentOrg.SyncFeatures.MultiTenant.Active {
|
||||||
|
limit = int(parentOrg.SyncFeatures.MultiTenant.Limit)
|
||||||
|
}
|
||||||
|
|
||||||
for index, org := range childOrgs {
|
for index, org := range childOrgs {
|
||||||
|
|
||||||
if index < 3 {
|
if index < limit {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
failToLoadOrgs = append(failToLoadOrgs, org.Id)
|
failToLoadOrgs = append(failToLoadOrgs, org.Id)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(org.CreatorOrg) > 0 && len(childOrgs) > 3 && shuffle.ArrayContains(failToLoadOrgs, userInfo.ActiveOrg.Id) {
|
if len(org.CreatorOrg) > 0 && len(childOrgs) > limit && shuffle.ArrayContains(failToLoadOrgs, userInfo.ActiveOrg.Id) {
|
||||||
parentOrg, err := shuffle.GetOrg(ctx, org.CreatorOrg)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("[ERROR] Failed to get parent org during getinfo: %s", err)
|
|
||||||
} else {
|
|
||||||
parent := shuffle.HandleCheckLicense(ctx, *parentOrg)
|
|
||||||
parentOrg := &parent
|
|
||||||
if !parentOrg.SyncFeatures.MultiTenant.Active {
|
|
||||||
userInfo.ActiveOrg = shuffle.OrgMini{
|
|
||||||
Id: parentOrg.Id,
|
|
||||||
Name: parentOrg.Name,
|
|
||||||
Role: userInfo.Role,
|
|
||||||
Branding: parentOrg.Branding,
|
|
||||||
Image: parentOrg.Image,
|
|
||||||
}
|
|
||||||
log.Printf("[INFO] Parent org %s has more than 3 child orgs and is not licensed. Moving user %s to parent org %s", parentOrg.Name, userInfo.Username, parentOrg.Name)
|
|
||||||
|
|
||||||
err = shuffle.SetUser(ctx, &userInfo, false)
|
userInfo.ActiveOrg = shuffle.OrgMini{
|
||||||
if err != nil {
|
Id: parentOrg.Id,
|
||||||
log.Printf("[WARNING] Failed setting user to parent org: %s", err)
|
Name: parentOrg.Name,
|
||||||
}
|
Role: userInfo.Role,
|
||||||
|
Branding: parentOrg.Branding,
|
||||||
resp.WriteHeader(200)
|
Image: parentOrg.Image,
|
||||||
resp.Write([]byte(`{"success": true, "reason": "Parent org has more than 3 child orgs and is not licensed. Moving to parent org. Contact support@shuffler.io for more information", "switch_parent": true}`))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if parentOrg.Licensed {
|
||||||
|
log.Printf("[INFO] Parent org %s is licensed. But Multi-tenant feature is not active. Moving user %s to parent org %s", parentOrg.Name, userInfo.Username)
|
||||||
|
} else {
|
||||||
|
log.Printf("[INFO] Parent org %s has more than 3 child orgs and is not licensed. Moving user %s to parent org %s", parentOrg.Name, userInfo.Username)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = shuffle.SetUser(ctx, &userInfo, false)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[WARNING] Failed setting user to parent org: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
reason := "Parent org has more than 3 child orgs and is not licensed. Moving user to parent org. Contact support@shuffler.io for more information"
|
||||||
|
|
||||||
|
if parentOrg.Licensed {
|
||||||
|
reason = fmt.Sprintf("Parent organization is licensed, but the maximum number of sub-organizations (%d) has been reached. You have been moved to the parent organization. Please contact support@shuffler.io for further assistance.", parentOrg.SyncFeatures.MultiTenant.Limit)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.WriteHeader(200)
|
||||||
|
resp.Write([]byte(`{"success": true, "reason": "` + reason + `", "switch_parent": true}`))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//if err == nil {
|
//if err == nil {
|
||||||
@@ -1139,7 +1160,7 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) {
|
|||||||
parentOrg, err := shuffle.GetOrg(ctx, parentOrgId)
|
parentOrg, err := shuffle.GetOrg(ctx, parentOrgId)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
parent := shuffle.HandleCheckLicense(ctx, *parentOrg)
|
parent := shuffle.HandleCheckLicense(ctx, *parentOrg)
|
||||||
if parentOrg.LeadInfo.IntegrationPartner || parent.SyncFeatures.Branding.Active {
|
if parent.SyncFeatures.Branding.Active {
|
||||||
parsedStatus = append(parsedStatus, "integration_partner")
|
parsedStatus = append(parsedStatus, "integration_partner")
|
||||||
|
|
||||||
// except theme take from parent org
|
// except theme take from parent org
|
||||||
@@ -1177,13 +1198,15 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
userInfo.ActiveOrg.Branding = shuffle.OrgBranding{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// for parent org branding
|
// for parent org branding
|
||||||
licenseOrg := shuffle.HandleCheckLicense(ctx, *org)
|
licenseOrg := shuffle.HandleCheckLicense(ctx, *org)
|
||||||
org = &licenseOrg
|
org = &licenseOrg
|
||||||
if org.LeadInfo.IntegrationPartner || org.SyncFeatures.Branding.Active {
|
if org.SyncFeatures.Branding.Active {
|
||||||
userInfo.ActiveOrg.Branding.Theme = org.Branding.Theme
|
userInfo.ActiveOrg.Branding.Theme = org.Branding.Theme
|
||||||
userInfo.ActiveOrg.Branding.DocumentationLink = org.Defaults.DocumentationReference
|
userInfo.ActiveOrg.Branding.DocumentationLink = org.Defaults.DocumentationReference
|
||||||
userInfo.ActiveOrg.Branding.SupportEmail = org.Branding.SupportEmail
|
userInfo.ActiveOrg.Branding.SupportEmail = org.Branding.SupportEmail
|
||||||
@@ -1192,6 +1215,8 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) {
|
|||||||
userInfo.ActiveOrg.Branding.BrandName = org.Branding.BrandName
|
userInfo.ActiveOrg.Branding.BrandName = org.Branding.BrandName
|
||||||
|
|
||||||
parsedStatus = append(parsedStatus, "integration_partner")
|
parsedStatus = append(parsedStatus, "integration_partner")
|
||||||
|
} else {
|
||||||
|
userInfo.ActiveOrg.Branding = shuffle.OrgBranding{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3875,11 +3900,12 @@ func handleCloudJob(job shuffle.CloudSyncJob) error {
|
|||||||
// Handles jobs from remote (cloud)
|
// Handles jobs from remote (cloud)
|
||||||
func remoteOrgJobController(org shuffle.Org, body []byte) error {
|
func remoteOrgJobController(org shuffle.Org, body []byte) error {
|
||||||
type retStruct struct {
|
type retStruct struct {
|
||||||
Success bool `json:"success"`
|
Success bool `json:"success"`
|
||||||
Reason string `json:"reason"`
|
Reason string `json:"reason"`
|
||||||
Jobs []shuffle.CloudSyncJob `json:"jobs"`
|
Jobs []shuffle.CloudSyncJob `json:"jobs"`
|
||||||
SyncFeatures shuffle.SyncFeatures `json:"sync_features"`
|
SyncFeatures shuffle.SyncFeatures `json:"sync_features"`
|
||||||
Subscriptions []shuffle.PaymentSubscription `json:"subscriptions"`
|
Subscriptions []shuffle.PaymentSubscription `json:"subscriptions"`
|
||||||
|
Licensed bool `json:"licensed"`
|
||||||
}
|
}
|
||||||
|
|
||||||
responseData := retStruct{}
|
responseData := retStruct{}
|
||||||
@@ -3962,6 +3988,15 @@ func remoteOrgJobController(org shuffle.Org, body []byte) error {
|
|||||||
shuffle.SetCache(ctx, subscriptionCacheKey, subscriptionsBytes, 1800)
|
shuffle.SetCache(ctx, subscriptionCacheKey, subscriptionsBytes, 1800)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
licenseCacheKey := fmt.Sprintf("org_licensed_%s", org.Id)
|
||||||
|
licensedBytes, err := json.Marshal(responseData.Licensed)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERROR] Failed to marshal Licensed for cache: %s", err)
|
||||||
|
} else {
|
||||||
|
|
||||||
|
shuffle.SetCache(ctx, licenseCacheKey, licensedBytes, 1800)
|
||||||
|
}
|
||||||
|
|
||||||
for _, job := range responseData.Jobs {
|
for _, job := range responseData.Jobs {
|
||||||
err = handleCloudJob(job)
|
err = handleCloudJob(job)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -167,6 +167,47 @@ const App = (message, props) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (userdata &&
|
||||||
|
userdata?.org_status?.includes("integration_partner") &&
|
||||||
|
userdata?.active_org?.image) {
|
||||||
|
|
||||||
|
const existingLinks = document.querySelectorAll("link[rel*='icon']");
|
||||||
|
existingLinks.forEach(link => link.parentNode.removeChild(link));
|
||||||
|
const newLink = document.createElement('link');
|
||||||
|
newLink.rel = 'icon';
|
||||||
|
newLink.type = 'image/x-icon';
|
||||||
|
try {
|
||||||
|
if (typeof userdata.active_org.image === 'string') {
|
||||||
|
if (userdata.active_org.image.startsWith('data:')) {
|
||||||
|
newLink.href = userdata.active_org.image;
|
||||||
|
} else if (userdata.active_org.image.startsWith('/')) {
|
||||||
|
newLink.href = userdata.active_org.image;
|
||||||
|
} else {
|
||||||
|
let mimeType = 'image/png';
|
||||||
|
newLink.href = `data:${mimeType};base64,${userdata.active_org.image}`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error("Image data is not in expected format:", userdata.active_org.image);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the new favicon link to head
|
||||||
|
document.head.appendChild(newLink);
|
||||||
|
const iframe = document.createElement('iframe');
|
||||||
|
iframe.style.display = 'none';
|
||||||
|
document.body.appendChild(iframe);
|
||||||
|
iframe.contentDocument.write('<link rel="icon" href="' + newLink.href + '">');
|
||||||
|
setTimeout(() => {
|
||||||
|
document.body.removeChild(iframe);
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error updating favicon:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [userdata]);
|
||||||
|
|
||||||
const checkLogin = () => {
|
const checkLogin = () => {
|
||||||
var baseurl = globalUrl;
|
var baseurl = globalUrl;
|
||||||
fetch(`${globalUrl}/api/v1/getinfo`, {
|
fetch(`${globalUrl}/api/v1/getinfo`, {
|
||||||
|
|||||||
@@ -1965,7 +1965,7 @@ const LeftSideBar = ({ userdata, serverside, globalUrl, notifications, }) => {
|
|||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{userdata?.licensed !== true && !userdata?.org_status?.includes("integration_partner") && expandLeftNav &&
|
{userdata?.licensed !== true && !userdata?.org_status?.includes("integration_partner") && expandLeftNav && !isProdStatusOn &&
|
||||||
<div style={{display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", }}>
|
<div style={{display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", }}>
|
||||||
<Button
|
<Button
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
|||||||
Reference in New Issue
Block a user