SalesforceToolkit开发日志v0.342

Release Note

v0.342 Release Note 
- Bugfix 
  - SOQL Module-Fix "&" causing query exception 
- New features 
  - SetPermission Module 
  - Add support for Permission Set 
- Function improvement 
  - None

此版本主要有两项更新

  1. 修复了SOQL中包含“&”会导致查询报错的问题。
  2. SetPermission模块增加Permission Set的支持。

概述

修复了SOQL中包含“&”会导致查询报错的问题

众所周知,为了标识HTTP请求URI的各个部分,使用了很多特殊的符号。例如https://,/,?,&,#,=等。

其中,&是用来分隔不同的HTTP查询参数,例如 http://example.com?param1=a&param2=2&param3=z

这里表示该请求携带三个查询参数,分别是param1、param2与param3。

所以在查询参数的值当中,就不应该再次出现&,否则服务器在解析URI时会因为额外的&导致对查询参数的切割出现错误,从而导致处理失败。

那么当确实需要使用&的时候该怎么办呢?

Javascript原生提供两个方法,分别是encodeURIComponent()和encodeURI()。

首先,根据https://datatracker.ietf.org/doc/html/rfc3986,由于URL中不可出现ASCII以外的字符,所以当URI中包含非ASCII字符时,需要对URI进行转码,然后由请求接收方进行解码。

Javascript既提供了encodeURI(),可以对整个URI进行百分号编码(percent-encoding),但不转码所有的保留字,方便后续将完整的URI进行打包传输;又提供了encodeURIComponent(),不管是不是保留字,整体全部进行百分号编码,将百分号编码的参数值放入URI中,就不会影响后续URI查询参数的解析。

本次出现的问题是在调用SFDC Rest API进行查询时,SOQL作为查询参数的值,使用了不对保留字下手的encodeURI(),导致当SOQL中包含&字符时,会被SFDC错误地切割,导致SOQL不完整,查询失败。

其实这个问题在较早前,在其他模块修复过一次,但没有做好grep调查。最终,该修的bug一个都跑不掉。

SetPermission模块增加Permission Set的支持

在SFDC UI中创建字段时,作为创建页面中的一步,可以在页面上直接勾选需要给哪些Profile设置该字段的权限。但是随着这几年SFDC产品经理的哲学思考,他觉得Object Permission与FLS等应该放到permission set上,并且大手一挥,将来Profile上不应该有任何的表与权限设定,很是豪迈。

作为SFDC的开发者,我很赞成这个哲学观点,但是,我有个疑问啊——通过UI创建字段时,也没有选择Permission Set的步骤啊?

难不成,伟大的产品经理是打算让我创建完字段之后,点进每个Permission Set挨个勾选吗?

也许伟大的产品经理自有打算,或者创建字段时可以选Permission Set已经安排在了路线图上。

但是,毕竟,现在还没有。

所以为了make it possible,我在SetPermission模块增加了为Permission Set设置Object Permission与Field Permission的选项。并且为了增加操作便利性,增加了Permission Set Picker,可以方便选择Permission Set。

总体上为查询Permission Set与Profile,为Permission Set与Profile设置权限,本质上都在同一张表里(ObjectPermissions与FieldPermissions),不同的只是ParentId,然而本质上Profile也是一种Permission Set,因为Profile也存在于Permission Set表,只不过type不同,一种是Regular,一种是Profile。

所以增加Permission Set模式只是调整了一下SOQL语句的条件。

关于增加Permission Set Picker,借由之前做User Maintain Module时增加的SelectTable web component,节省了大量的重复劳动,此功能就演变成了做一个modal并塞一个selectTable进去。

计划还会增加Apex class,Tab与Record Type的分配,二阶段继续增加user permission与特殊权限的分配。不过由于工作量与测试量超出目前的可用时间(由于目前处在一个管理上很混乱的项目,导致我可用时间甚至是负数XD)。待恢复足够的可支配时间,会继续有限拓展该模块。

Chrome Extension
Salesforce Toolkit
https://chrome.google.com/webstore/detail/salesforce-toolkit/kgjlcplagigepdkknapcdijkcdbkehjp?hl=zh-CN

Microsoft Edge Extension
Salesforce Toolkit
https://microsoftedge.microsoft.com/addons/detail/ajljhokkkbjedmnnkgbmlfjcjjjoemca

SalesforceToolkit开发日志v0.341

Release Note

v0.341 Release Note
- Bugfix
    - None
- New features
    - Metadata Module - Add support for custom label
    - Login Module - Optimize config saving strategy to local first
- Function improvement
    - None

此版本主要有两项更新

  1. 在Metadata模块中新增了Custom Label的创建与更新功能。
  2. 调整了配置信息的存储策略,现在优先本地存储,但仍可以手动进行远程同步。

概述

在Metadata模块中新增了Custom Label的创建与更新功能

在之前的更新中,我们添加了CustomLabel的翻译创建与更新功能,目的是帮助大家提高维护CustomLabel翻译的效率。在此基础上,有些朋友提出手动创建CustomLabel本身也是一件效率较低的事情,所以我们进行了改进。

由于对CustomLabel没有公开的数据操作方式,所以原理上我们仍然是通过SOAP API方式调用Metadata API,依然是手动拼接XML。

与CustomLabel Translation的操作逻辑不同,Translation可以创建/更新的前提是CustomLabel必然已经存在。所以,我们可以通过同一个XML同时进行没有翻译创建翻译,有翻译更新翻译的操作。但是Custom Label的创建和更新接口是两个完全不同的XML类型。因此,我们在弹出窗口中增加了一个选项,让你选择是创建还是更新。填写内容的方式仍然是传统的XXXX,YYYY模式,XXXX为API Name,YYYY为Value。

在处理返回值时,CustomLabel接口出现了特殊性——返回结果会多出一行success节点值为false,fullName为空但带有属性xsi:nil=”true”的result。这导致原有的错误处理代码做出了错误的结果判断。我们试过切换API版本等措施,但都无法定位和解决此问题,所以只能在判断结果时额外循环一次移除这种多余的result节点。

将来,我们可能会增加CustomLabel删除的选项,但由于被引用的问题,大部分CustomLabel很难直接删除,所以这个功能不会优先考虑。

至于查询系统当前的CustomLabel,由于目前Tooling API可以直接查询CustomLabel表,SOQL模块已经支持Tooling API查询,所以我们短期内不会考虑这个功能。

调整配置信息的存储策略,现在优先本地存储,但仍可以手动进行远程同步

Chrome插件为了方便用户跨设备同步配置信息,提供了Chrome.storage.sync接口。这个接口的行为与浏览器的标准local.storage类似,但并不会存储在浏览器的Storage空间中,而是存储在Google账号的云空间中。需要注意的是,这些信息属于用户个人的Google账号,插件的开发者并不能看到。如果用户没有登录Google账号,Chrome.Storage.Sync接口的行为会降级到Chrome.Storage.Local接口。这个接口与浏览器标准的local.Storage不同,它是存储在独立的浏览器沙盒空间中。

之前的配置信息同步逻辑是,插件初次加载时从云端获取配置信息,如果配置信息发生变动,如新增、修改、删除,则实时存储回云端。其他配套功能如配置导出等,都是直接从云端配置读取,而不是使用已加载的页面信息,这样可以避免信息状态同步的问题。

虽然这个机制运行良好,但有些用户反映出现了配置被反复覆盖回某个时间点的版本的问题。我们调查发现,出现这种现象的用户都是因为Chrome账号服务被人为阻塞导致的——只阻塞了同步到云端,但没有阻塞从云端获取。这就导致无论本地信息如何变动,只要重新加载插件,配置就会恢复到云端版本。

为了根本解决云端配置同步的潜在问题,我们决定优先使用本地版本(Chrome.Storage.Local)的配置信息。从新版本开始,配置信息的来源将优先从本地获取,所有的变动也将只修改本地存储的信息。同时,我们增加了两个按钮,用于手动将本地配置信息存储到云端,或者从云端获取配置信息并合并到本地。

同时,由于当前所有配置信息在本地的存储状态并不确定,只有云端版本是我们可以信赖的。所以初始加载逻辑变为先从本地获取,如果从本地无法获取到信息,则从云端获取,并将获取到的信息存储到本地。这样,在版本切换时,我们可以将云端配置信息转变为本地版本。

信息安全是我们的重中之重,这个插件不会收集任何用户输入的信息,无论是在云端还是本地。请放心使用。