Fix - bunch of branding and licensing issue

This commit is contained in:
lalitdeore12@gmail.com
2025-10-15 17:49:23 +05:30
parent f6d069f708
commit 33e431bebd
3 changed files with 109 additions and 33 deletions
+67 -32
View File
@@ -76,6 +76,7 @@ type retStruct struct {
IntervalSeconds int64 `json:"interval_seconds"`
Reason string `json:"reason"`
Subscriptions []shuffle.PaymentSubscription `json:"subscriptions"`
Licensed bool `json:"licensed"`
}
type Contact struct {
@@ -951,42 +952,62 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) {
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 {
if index < 3 {
if index < limit {
continue
}
failToLoadOrgs = append(failToLoadOrgs, org.Id)
}
if len(org.CreatorOrg) > 0 && len(childOrgs) > 3 && 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)
if len(org.CreatorOrg) > 0 && len(childOrgs) > limit && shuffle.ArrayContains(failToLoadOrgs, userInfo.ActiveOrg.Id) {
err = shuffle.SetUser(ctx, &userInfo, false)
if err != nil {
log.Printf("[WARNING] Failed setting user to parent org: %s", err)
}
resp.WriteHeader(200)
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
}
userInfo.ActiveOrg = shuffle.OrgMini{
Id: parentOrg.Id,
Name: parentOrg.Name,
Role: userInfo.Role,
Branding: parentOrg.Branding,
Image: parentOrg.Image,
}
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 {
@@ -1139,7 +1160,7 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) {
parentOrg, err := shuffle.GetOrg(ctx, parentOrgId)
if err == nil {
parent := shuffle.HandleCheckLicense(ctx, *parentOrg)
if parentOrg.LeadInfo.IntegrationPartner || parent.SyncFeatures.Branding.Active {
if parent.SyncFeatures.Branding.Active {
parsedStatus = append(parsedStatus, "integration_partner")
// except theme take from parent org
@@ -1177,13 +1198,15 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) {
break
}
}
} else {
userInfo.ActiveOrg.Branding = shuffle.OrgBranding{}
}
}
} else {
// for parent org branding
licenseOrg := shuffle.HandleCheckLicense(ctx, *org)
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.DocumentationLink = org.Defaults.DocumentationReference
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
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)
func remoteOrgJobController(org shuffle.Org, body []byte) error {
type retStruct struct {
Success bool `json:"success"`
Reason string `json:"reason"`
Jobs []shuffle.CloudSyncJob `json:"jobs"`
SyncFeatures shuffle.SyncFeatures `json:"sync_features"`
Success bool `json:"success"`
Reason string `json:"reason"`
Jobs []shuffle.CloudSyncJob `json:"jobs"`
SyncFeatures shuffle.SyncFeatures `json:"sync_features"`
Subscriptions []shuffle.PaymentSubscription `json:"subscriptions"`
Licensed bool `json:"licensed"`
}
responseData := retStruct{}
@@ -3962,6 +3988,15 @@ func remoteOrgJobController(org shuffle.Org, body []byte) error {
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 {
err = handleCloudJob(job)
if err != nil {
+41
View File
@@ -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 = () => {
var baseurl = globalUrl;
fetch(`${globalUrl}/api/v1/getinfo`, {
+1 -1
View File
@@ -1965,7 +1965,7 @@ const LeftSideBar = ({ userdata, serverside, globalUrl, notifications, }) => {
</div>
) : 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", }}>
<Button
variant="outlined"