The primary objectives for the Cobalt 3.7 Release were to:
- Fix priority bugs and close gaps in functionality identified by support, implementation teams, and customers as well as items uncovered by our automated testing sprints.
- Produce a stable, cross-version compatible release of the Cobalt product.
- Incorporate automated testing into the Cobalt product release process.
- Achieve AppSource certification for our entire product (Core, Membership, and Certification solutions).
- Improve the portal user experience in an impactful way.
The Cobalt 3.7 will be considered a success if the following criteria are met.
- All Priority 1 bugs selected for inclusion in the release are implemented or fixed during this project.
- Cobalt 3.7 passes regression testing in Cobalt’s Dynamics 365 8.2 on-premises, 9.1 on-premises, and 9.1 online UAT environments.
- We can test at least 40% of testing and regression scenarios in this release using automated tests that are incorporated into the regression testing process.
- We can successfully list our product(s) on AppSource.
- Resolve bugs and gaps in functionality related to single sign-on and web elements to provide a more seamless experience for portal visitors. This will be achieved when all SAML SSO-related cases approved for inclusion in sprints have been resolved and all related feedback addressed.
- Implement an updated portal home page with a design that more closely matches the rest of the portal as well as a more complete set of tiles and link logic so that it is easier to navigate. This will be accomplished when the portal homepage redesign cases in each sprint have been resolved, all customer feedback for them has been addressed, and no existing functionality is lost.
Hosting Implications: Cross-Domain Hosting
In 2019, IETF (Internet Engineering Task Force) revised their standard when it comes to protecting against CSRF (cross-site request forgery) request. After this adjustment in the standard was made, Google announced their effort to make adjustments to their Google Chrome browser to accommodate this update. The deployment of this standard to Chrome, with other browsers shortly following suit, introduced a breaking change for all our client’s Portal and ISV web application, regardless of the Cobalt version that they were on. To remedy this, we needed to adjust the Web.config files for all of our UI based web applications (portal and ISV) to ensure that our web applications leveraged a secure samesite cookie. Going forward, we are instituting a new policy when it comes to hosting our portal web application, in particular when it comes to leveraging our Web Elements functionality. We are now only supporting web element portals that are hosted within the same domain as the parent site (i.e. CMS). We are instituting this policy primarily because we are anticipating that the IETF (or any major vendor in the web browser space such as Google or Microsoft) will be continuing down this path of increasing security. By having the web elements portal be within the same domain as the parent site, we are hoping to prevent further break changes to our web applications. In order to successfully host our web elements portal in the same domain as the parent CMS site, the client needs to coordinate with Cobalt in the following ways:
- Client provisions a new DNS entry for the current web element site (clientwebelements.cobaltsaas.com) so that it is within the CMS’s domain (client.org). Popular choices by current clients who already have this sub-domain in place for this new DNS name relative to client domain have been members.client.org and portal.client.org.
- Client provides Cobalt an SSL certification for that domain prior to go-live date. Client will be responsible for ensure that this certificate stays up to date on a rolling basis by coordinating with Cobalt through support tickets.
- On the day of go-live, Client will be responsible for updating the CMS in question and coordinating with other third-party vendors in regard to the DNS update (i.e. Higher Logic, WordPress, etc).
- On the day of go-live, Client and Cobalt will be responsible for updating configuration values inside of CRM to point to this new DNS name. This includes things such as web element configurations, cache configuration, email templates, IIS rewrite rules, and other various configuration values (see implementation/upgrade notes for more details).
- Cobalt will need to ensure that the same site secure cookie configuration is in place for the web element website via the web.config (see implementation/upgrade notes for more details).
With the requirements bestowed upon us by Microsoft to meet their code quality standards for the ISV Embed license, we needed to rework and remove some code around our autonumbering functionality. This required that instead of relying on locks to ensure that autonumbering values are unique on a sandbox processing worker by sandbox processing worker basis, that we instead leverage our autonumbering API for all our clients. This would normally only be setup for our clients who have larger sets of volume or are load balanced with multiple CRM virtual machines. In the future, we anticipate using the out-of-the-box autonumbering functionality introduced in the 9.X version of Dynamics once we have deemed that it can sustain comparable amounts of load that our API currently handles today. See implementation/upgrade notes for more details.
Supported CRM Versions
It is recommended that clients use, at the very least, one of the below versions of CRM for implementations when upgrading to 3.7.0. Going beyond these versions is up to the project team’s discretion. For implementations or projects that are targeting an online go-live, it is best to patch CRM to the latest 9.x version, as to have the smallest version gap between what is on-premises and what is online. This is because development and stage environments are always on-premise. Client implementations on 9.X must upgrade to at least the 9.X May version.
9.X Version: May 2020 184.108.40.206
8.X Version: March 2020 220.127.116.11
Cases and Background
In this release, most of the work done around the portal was related to the portal redesign. As of this release, the portal homepage has been restyled so that it looks more modern and is consistent with the styling on other pages of our portal, while also improving on our data usage that is used to render this page. Additionally, the individual controls, as well as what controls are on the homepage (and their location on the homepage), are configurable via the Web Element Designer. Clients have the option to upgrade to this new home page framework or stay with their current home page if they have a customized variation already, but from a product standpoint, we will not be investing in the deprecated home page logic anymore and will only be investing in this new framework in subsequent releases.
|Custom Theme of Custom Web Element does not persist in Stand Alone Portal via Sitemap Embedding
|Elegantly Handle Bad Data + Merge Text
|Prior to this case, if an Order Source had invalid merge text within its Order Source Link Text field, the My Orders page would load over and over for an indefinite period. This rendered the My Order page inaccessible. After this case, the My Orders page will load even if the merge text is incorrect. That said, the Status of Orders with Order Sources where the merge text is incorrect will be marked ‘Not Payable’.
|Add spacing to comma-delimited list of accepted file types in document upload control validation
|This case added spacing to the file types displayed in the accepted file types validation present on all our document upload controls by default.
|Web Elements – Add More Filters to List Views
|Before this case, the number of filters which could be specified on a custom grid or list Web Element was limited to two. Now, new Filter dropdowns are dynamically added as needed.
|Update jQuery Version used to be Configurable
|This case provisioned a field, JQuery Version URL, on the Settings record where a jQuery version can be specified using a URL. If the field is null, our product now defaults to version 3.4.1. NOTE: Any client specific jQuery scripts will need to be updated to work with the 3.X version (see implementation notes).
|Home Page Rework
|This is the parent case under which the sub-cases which provisioned the new portal homepage framework were filed. The result of these changes is that the portal homepage is now configurable via the web element designer. Individual homepage elements can be modified on an ad hoc basis and can be added or removed from the homepage without issue. Additionally, there were UX improvements around the membership control.
|Web Application Configurations via Service Configuration
|This case provisioned the Service Configuration used to store portal homepage layout data.
|Session Expiration Popup Warning
|This case provisioned a session expiration pop-up warning which can be configured to appear in the portal and/or ISV when a user’s session is about to expire.
|URL Typo in Social Share Link
|The email social sharing icons for classes had an incorrect query string parameter in the URLs generated for the Class details page. This case corrected that issue.
|Form: Conditionally Require on Question Logic Entity
|This case fixed a bug wherein Conditionally Require Question Logic was broken when the parent Question was hidden. Example: Country is a hidden field on a Form; if Country = China, a specific field should be required. This example would have failed to operate as expected prior to this case.
|Form Option Sets – No NULL Option for End Users
|This case resolved an issue with our option set controls where those controls did not have a null value option.
|Cobalt 3.6 Queries/ViewSummary.ascx references functions that DNE
|This case addressed a bug introduced in Cobalt 3.6 where the Custom List and My List pages within the Web Element Designer would throw an error.
|Conditionally Enabled Field Not Locked
|Prior to this case, using Question Logic to conditionally logic a field would not lock the field if the Expected Value field is null. This was changed so that end users could lock fields as they pleased without having to specify some impossible Expected Value to ensure the field was not improperly unlocked.
SSO, Authorization, and Authentication Updates
3.7 brings our product up to industry standards regarding SAML SSO. Highlights include the fact that IdP-initiated flows are now supported and that our product now allows custom attributes to be passed easily via non-dev configuration. Additionally, the authentication cache was reworked such that the CMS User Role entity is no longer responsible for both authorization and authentication. Now, the CMS User Role entity only handles authorization (roles and groups) while the CMS User Identity Definition entity handles authorization (specifying login information, email, friendly name).
|Read / Write Custom SAML Attributes
|This is the parent case which set up the framework by which custom attributes can be specified for use in SAML SSO-configurations. In other words, this case is what allows end users to, for instance, specify an alternate primary key in a situation where Cobalt is a service provider (SP) or pass additional, custom Attributes to an SP when Cobalt is the identity provider (IdP).
|Workaround for Handling SAML Login Assertion when user triggers SSO flow from within Web Element (Non-SSO Flow)
|This case added a Service Configuration Property to the widget site Service Configuration, ‘HideLoginButtons’, which, when set equal to True, hides all of Cobalt’s base login buttons within the portal and any associated Web Elements. The goal here was to prevent end users from using our base login control instead of an SSO-enabled login control in certain scenarios.
|Framework Update – Authentication Cache
|This case provisioned a feature in our Authentication Cache framework wherein users can now specify their desired Evaluation and Cache behaviors on a per CMS User and User Identity Definition basis.
|CMS User Identity (Non-SSO Flow)
|This was the parent case under which the sub-cases which provisioned the new CMS User Identity Definition entity were filed. This new entity helps segment authentication and authorization functionalities by making this new entity responsible for the former and CMS User Roles responsible for the latter.
|SSO Request Handling – Logging Update
|This feature allows users to specify that trace logs should only be generated for SSO events by using the web.config page.
|SAML Role/Group Formatting (Non-SSO Flow)
|This case brought the syntax our product uses to display role and group information on the ~/Metadata.ashx page in line with the industry standard.
|SAML Metadata Update for Filtering Roles and Groups
|This case added two Service Configuration Properties, ‘RelevantRoles’ and ‘RelevantGroups’, to the Identity Provider Service Configuration. Using these two Properties, end users can now filter what Role and Group information are sent to individual service providers (SP).
|IDP Initiated SAML SSO flow w/ Cobalt As Sessions Participant
|After this feature’s implantation, Cobalt’s product now supports IdP-initiated flows where cobalt is an SP.
|Incorrect SSOState Evaluation on Subsequent SAML2IDP Login Request
|This case corrected an issue wherein an end user attempting to log on via SSO would not be properly logged on via SSO if they were routed into the password reset process.
|Improper Relay State Handling with SAML SSO
|Prior to this bug-fix, if a user logged on via SSO on a given page of Cobalt’s portal, they would not be redirected to that page on completion of the SSO flow.
Locks are when data is made read-only by a process to ensure other processes cannot interfere with the running process. Though such locks are typically only a few milliseconds in duration (if not less), Microsoft highlighted the locks in our product as a blocker for certification on AppSource. As such, the cases addressed in 3.7 dealt primarily with removing these locks.
|Product Locking Issues Persisting
|This was the parent case under which all lock removal cases were filed. The locks in our product were one of the primary reasons Microsoft said we could not be listed on AppSource and so removing those locks was critical to the project’s success.
|Remove SDK All Column References
|Most likely for performance reasons, Microsoft discourages the use of retrieving all columns of an entity.
|Client-Side Updates for AppSource – High Priority Only
These are items that were introduced into our Engagement Dynamics product offering.
|Allow for Cron Jobs to execute a workflow against a Collection of Entities (Queried Crons)
|This case provisioned queried cron functionality within Cobalt’s base product. Queried crons are Cron Jobs which execute a specified Workflow on the records returned by a specified Query at regular intervals.
|Cobalt Upgrade Workflow for Custom Roll out steps
|This case provisioned a Workflow, executed from the Settings record, which completes all necessary CRM-side configuration to facilitate an upgrade from lower versions of Cobalt to 3.7. The goal is to update this Workflow with each release.
|SQL Configuration Exception Throwing
|Before this case was implemented, SQL connection configuration issues would often go undetected because exceptions were not thrown in certain scenarios. After this case’s implementation, SQL connection configuration issues will result in exceptions being thrown within the portal and ISV.
|Add Attendee to Meeting Reg: Exclude Currently Registered Contacts & Contacts Being Registered in the Current Wizard
|Prior to this fix, Contacts who were trying to add an Attendee to a Meeting could search for and find themselves, even if they had already registered. This case corrected that issue.
|Publish to portal on election not respected on portal
|In older versions of Cobalt, the Publish to Portal flag on the Election entity was not respected. This case corrected that issue.
These are items that were introduced into our Engagement Dynamics product offering.
|Display on Portal flag on Member Type records not respected
|Originally, Fees associated with Member Types where the Display on Portal flag was set to No were displayed on the portal during the membership application process. This case resolved that issue.
|Order for dues getting paid can update Date Paid on Dues Item twice
|The Date Paid field on Dues Items used to get hit by two update events when a user paid their Dues Order. This caused problems in cases where an organization wanted to send a confirmation email to a member when their Dues Item was marked Paid as two emails would be sent. Now it is only hit once as one would expect.
These are items that were introduced into our Certification Dynamics product offering.
|UX – Add Primary Naming Strategy to Exam Entity
|This case added a naming strategy to Cobalt’s Exam entity.
These are items that were introduced into our Engagement Dynamics product offering, specifically when it involves Sales or Accounting.
|Update code to handle Product Bundles
|The Cobalt Product now supports Product Bundles. This case is what built out that functionality. Shipping and Tax accounting data will be derived from the Product Bundle’s pricing data while other GL Entries will be derived from the child Products’ data.
|Amounts on the Sales Order Payments Need To Be Set for all Sales Order Payments
|Previously, Sales Order Payment Amount fields were only set when a Payment was being used to pay down multiple Orders. This was an issue for RAMCO as some of their reports relied on this Amount field. This case ensures that the Amount field is now set in all scenarios.
|Set Invoice Balance = $0.00 when Invoice Status Reason = Canceled
|This case brought the Invoice entity’s functionality in line with Cobalt’s Accounting module. Since, based on Cobalt accounting data, a Canceled Invoice has a Balance of $0.00, this case ensures that the Balance field on Invoices are set to $0.00 when their Status Reason is Canceled.
|Orders with freight amount and product-specific receivables Product GL Accounts set create GL entry errors
|In scenarios where an Order had a Freight amount and an associated Order Detail had an Existing Product with a Product GL Account of Type = Receivables, the subsequent GL Entries were incorrect. This case corrected that problem.
|Inactive Product GL accounts direct GL entries to the wrong account
|Our accounting module was not filtering Inactive Product GL Accounts. The result was the Inactive Product GLs were still used as if they were Active. This case corrected that issue.
|Accounting Export Wizard Throws an Exception on Form.aspx Page
|The Accounting Export wizard was throwing an error. This case fixed that.
|Remove CrmEntityTypeCode from Generated Classes or Enforce Dynamic Retrieval
|This case ensures that any references to ObjectTypeCode in our product is generated dynamically. This avoids the issue where, if Cobalt’s Solutions were imported in an ‘incorrect’ order, the ObjectTypeCodes for our custom entities would not match the hardcoded values in various wizards.
|Abort “In-Progress” Crons on Application Start
|This case ensures that, if a server-side issue disrupts the execution of a given Cron, the relevant Cron Schedule in CRM will be marked as Aborted.
|Cache Reader not Firing Correctly
|Issue with the cache data reader when retrieving multiple records resulted in the system falling back onto SQL or CRM web services.
|Plugin Registration – Recommended Event Dispatcher appears to not be used currently
|Auto-naming strategies for records were not always getting executed when there was no corresponding server event handler.
|Client Event Handlers not Preventing Save Actions from Occurring for Violated Validations for 9.X
|For clients on 9.X on-premise or online, we were not properly preventing saves from executing when we identified that the inputted data was violating a rule that we maintain in code.
|Multi-Select Option set Update not Persisting
|Depending on the update done to a particular multi-select option set, the new value was never posted to CRM.
|URL Encoding Issues w/ Encrypting and Decrypting Logic
|In various edge case situations, if an encrypted value was used as a query string parameter, the system may not be able to decrypt the value as it was not properly URL encoded first.
|Update Cron Scheduler to Dispatch non-Workflow triggered Crons Asyncronously
|This case allows for multiple long running Cron schedules to be executed within the context of the ISV concurrently.