Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Security enhancements #188

Merged
merged 38 commits into from
Sep 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
4d16742
Added StripInaccessibleRecordFields__c setting
jongpie Aug 25, 2021
b87417c
Added all CMDT objects to LoggerAdmin.permissionset
jongpie Aug 25, 2021
403cfc2
Added LogEntryDataMaskRule__mdt object for applying data mask rules t…
jongpie Aug 25, 2021
f479a6e
Added CMDT rules for credit card numbers & social security numbers
jongpie Aug 25, 2021
978469d
Pre-refactored getJson() after reviewing with @jamessimone
jongpie Aug 25, 2021
4064a84
Added setting ApplyDataMaskRules__c to control if CMDT data mask rule…
jongpie Aug 25, 2021
7726eb5
Incorporated @jamessimone's idea of being able to specify a length of…
jongpie Aug 26, 2021
64ed547
Testing out re-enabling codecov integration
jongpie Aug 26, 2021
fc7f2fb
Added tests for StripInaccessibleRecordFields__c
jongpie Aug 26, 2021
0cadbf6
Added some user managament settings to scratch-def files
jongpie Aug 26, 2021
722963b
Split 'credit card number' rule into 3 separate, company-specific rules
jongpie Aug 26, 2021
de2d1f5
Eliminated field NumberOfCharactersToKeepUnmasked__c
jongpie Aug 26, 2021
aa5f529
Simplified part of the sanitizeMessage() method
jongpie Aug 26, 2021
ce5fa57
Added new field MessageSanitized__c + lots of optimizations in LogEnt…
jongpie Aug 27, 2021
ca73544
Added test suites for each module
jongpie Aug 27, 2021
dfbbdbe
Added a few more FLS asserts as sanity checks
jongpie Aug 27, 2021
66f5d13
Moved some test helper methods to LoggerTestUtils, cleaned up LogEntr…
jongpie Aug 27, 2021
7c208a1
Renamed MessageSanitized__c to MessageDataMasked__c
jongpie Aug 27, 2021
fe36ba5
Fixed lazy-loading issue with AuthSession
jongpie Aug 27, 2021
874c4bd
Renamed MessageDataMasked__c (again) to MessageMasked__c
jongpie Aug 27, 2021
fa1d47a
Switched to using a new field, ReplacementRegEx__c
jongpie Aug 27, 2021
844ae27
Optimized setTagsDetails()
jongpie Aug 28, 2021
f8e2438
Renanmed MessageRegEx__c to SensitiveDataRegEx__c, renamed sanitizeMe…
jongpie Aug 28, 2021
ab9d3d8
WIP: added support for masking record JSON (in addition to message)
jongpie Aug 28, 2021
2066565
Finished adding support for masking record JSON
jongpie Aug 30, 2021
74dc3e7
Fixed some issues with the included data mask rules
jongpie Aug 30, 2021
4a5ad3e
Fixed missing space issue with provided data mask rules
jongpie Sep 8, 2021
7b43158
Bumped version number
jongpie Sep 8, 2021
cbe0631
Reverted a few changes in LogEntryRecordPage.flexipage
jongpie Sep 8, 2021
0ef3f62
Fixed FLS in Admin.profile
jongpie Sep 8, 2021
4e7dbbe
Added missing update for builder.tagDetailsAreSet, updated apex docs
jongpie Sep 8, 2021
ba7b4b2
Incorporated the latest changes @jamessimone implemented in v4.6.6
jongpie Sep 9, 2021
36da275
Flow bugfixes + pipeline enhancements (#200)
jongpie Sep 13, 2021
bcc594d
Switched back to using extra-tests folder, created LogEntryEventBuild…
jongpie Sep 13, 2021
07d82af
Added new step to pipeline to create an unvalidated package version &…
jongpie Sep 13, 2021
de176f8
Added static code analysis / PMD (#201)
jamessimone Sep 13, 2021
dd8ce0b
Fixed line breaks not working when calling System.debug()
jongpie Sep 13, 2021
e13d245
Created new package version v4.6.7
jongpie Sep 14, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"parser": "@babel/eslint-parser",
"parserOptions": {
"requireConfigFile": false,
"babelOptions": {
"parserOpts": {
"plugins": ["classProperties", ["decorators", { "decoratorsBeforeExport": false }]]
}
}
},
"ignorePatterns": ["**/*.html", "**/*.cmp", "**/*.cmp-meta.xml", "**/*.css", "**/*.test.js", "**/*js-meta.xml", "**/*.json"],
"plugins": ["@lwc/eslint-plugin-lwc", "@salesforce/eslint-plugin-aura"],
"extends": ["@salesforce/eslint-config-lwc/recommended"],
"rules": {
"eqeqeq": "off",
"no-console": "off",
"no-unused-expressions": "off",
"semi": "off",
"@lwc/lwc/consistent-component-name": "error",
"@lwc/lwc/no-api-reassignments": "off",
"@lwc/lwc/no-async-operation": "off",
"@lwc/lwc/no-deprecated": "error",
"@lwc/lwc/no-document-query": "error",
"@lwc/lwc/valid-api": "error"
}
}
3 changes: 2 additions & 1 deletion .forceignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ nebula-logger/main/default/**

# Directory/package-specific README files
**/README.md
**/.content/**

# LWC configuration files
**/jsconfig.json
**/.eslintrc.json

# LWC Jest
**/__tests__/**
**/__tests__/**
141 changes: 92 additions & 49 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Unique name for this workflow
# Pipeline for Nebula Logger
name: Deployment

on:
Expand Down Expand Up @@ -39,12 +39,11 @@ on:
- 'sfdx-project.json'

jobs:
local-tests:
name: 'Local Tests'
code-quality-tests:
name: 'Code Quality Tests'
runs-on: ubuntu-latest
environment: Test
steps:
# Checkout the code
- name: 'Checkout source code'
uses: actions/checkout@v2

Expand All @@ -56,41 +55,55 @@ jobs:
- name: 'Install npm'
run: npm install

# Install Salesforce CLI
- name: 'Lint Lightning Components'
run: npm run lint:lwc

- name: 'Prettier code formatting verification'
run: npm run prettier:verify

- name: Install Salesforce CLI
run: npm install sfdx-cli --global
# run: |
# wget https://developer.salesforce.com/media/salesforce-cli/sfdx-linux-amd64.tar.xz
# mkdir sfdx-cli
# tar xJf sfdx-linux-amd64.tar.xz -C sfdx-cli --strip-components 1
# ./sfdx-cli/install

# Start local testing
# TODO uncomment
# Prettier formatting
# - name: 'Code formatting verification with Prettier'
# run: npm run prettier:verify
# TODO uncomment
# Lint LWC
# - name: 'Lint Lightning Web Components'
# run: npm run lint:lwc
# LWC unit tests

- name: Install & run SFDX Scanner
run: |
sfdx plugins:install @salesforce/sfdx-scanner
sfdx scanner:run --pmdconfig config/pmd-ruleset.xml --target . --engine pmd --severity-threshold 3

lwc-tests:
name: 'LWC Tests'
needs: [code-quality-tests]
runs-on: ubuntu-latest
environment: Test
steps:
- name: 'Checkout source code'
uses: actions/checkout@v2

- name: 'Setup node'
uses: actions/setup-node@v2
with:
node-version: '14'

- name: 'Install npm'
run: npm install

- name: Install Salesforce CLI
run: npm install sfdx-cli --global

- name: 'Run LWC Tests'
run: npm run test:lwc

# Upload code coverage data for LWC
# - name: 'Upload code coverage for LWC to Codecov.io'
# uses: codecov/[email protected]
# with:
# token: ${{ secrets.CODECOV_TOKEN }}
# flags: LWC
- name: 'Upload LWC code coverage to Codecov.io'
uses: codecov/[email protected]
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: LWC

scratch-org-tests:
name: 'Scratch Org Tests'
needs: [code-quality-tests]
runs-on: ubuntu-latest
environment: Test
steps:
# Checkout the code
- name: 'Checkout source code'
uses: actions/checkout@v2

Expand All @@ -102,18 +115,9 @@ jobs:
- name: 'Install npm'
run: npm install

# Install Salesforce CLI
- name: Install Salesforce CLI
run: npm install sfdx-cli --global
# run: |
# wget https://developer.salesforce.com/media/salesforce-cli/sfdx-linux-amd64.tar.xz
# mkdir sfdx-cli
# tar xJf sfdx-linux-amd64.tar.xz -C sfdx-cli --strip-components 1
# ./sfdx-cli/install

# Start remote testing

# Store secrets for dev hubs
- name: 'Populate DevHub Auth Files'
shell: bash
run: |
Expand Down Expand Up @@ -142,31 +146,70 @@ jobs:
with:
args: '120'

- name: 'Deploy Metadata'
run: npm run deploy
- name: 'Push Metadata'
run: sfdx force:source:push --forceoverwrite

- name: 'Run Apex Tests'
run: npm run test:apex

# Delete test files that Codecov is unable to parse
# - name: 'Delete unsupported code coverage files'
# run: rm ./tests/apex/test-result-707*-codecoverage.json
- name: 'Delete unsupported code coverage files'
run: rm ./tests/apex/test-result-707*-codecoverage.json

# Upload code coverage data for Apex
# - name: 'Upload code coverage for Apex to Codecov.io'
# uses: codecov/[email protected]
# with:
# token: ${{ secrets.CODECOV_TOKEN }}
# flags: Apex
- name: 'Upload Apex test code coverage to Codecov.io'
uses: codecov/[email protected]
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: Apex

- name: 'Delete Scratch Org'
run: npm run org:delete:noprompt
if: ${{ always() }}

create-and-install-test-package-version:
name: 'Create & Install Test Package Version'
needs: [lwc-tests, scratch-org-tests]
if: ${{ github.event_name == 'pull_request' }}
runs-on: ubuntu-latest
environment: Test
steps:
- name: 'Checkout source code'
uses: actions/checkout@v2

- name: 'Setup node'
uses: actions/setup-node@v2
with:
node-version: '14'

- name: 'Install npm'
run: npm install

- name: Install Salesforce CLI
run: npm install sfdx-cli --global

- name: 'Populate Org Auth Files'
shell: bash
run: |
echo ${{ env.DEVHUB_SFDX_URL }} > ./DEVHUB_SFDX_URL.txt
echo ${{ env.NEBULA_PKG_DEMO_SANDBOX_SFDX_URL }} > ./NEBULA_PKG_DEMO_SANDBOX_SFDX_URL.txt
env:
DEVHUB_SFDX_URL: ${{ secrets.DEVHUB_SFDX_URL }}
NEBULA_PKG_DEMO_SANDBOX_SFDX_URL: ${{ secrets.NEBULA_PKG_DEMO_SANDBOX_SFDX_URL }}

- name: 'Authorize Orgs'
run: |
sfdx auth:sfdxurl:store --sfdxurlfile ./DEVHUB_SFDX_URL.txt --setalias nebula-logger-packaging --setdefaultdevhubusername
sfdx auth:sfdxurl:store --sfdxurlfile ./NEBULA_PKG_DEMO_SANDBOX_SFDX_URL.txt --setalias nebula-logger-package-demo

- name: 'Create & Install Unvalidated Package Version'
run: npx pwsh ./scripts/create-and-install-unvalidated-package-version.ps1 -targetusername nebula-logger-package-demo

- name: 'Reinstall Latest Released Package Version'
run: npx pwsh ./scripts/install-latest-released-unlocked-package-version.ps1 -targetusername nebula-logger-package-demo

# TODO finish auto-creation & promotion of unlocked package + committing changes to docs
# create-package-version:
# name: 'Create Package Version'
# needs: [local-tests, scratch-org-tests]
# needs: [code-quality-tests, lwc-tests, scratch-org-tests]
# runs-on: ubuntu-latest
# environment: Test
# steps:
Expand Down
7 changes: 1 addition & 6 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,12 @@
.settings/
.sfdx/
.vscode/
examples/
nebula-logger/main/default/
nebula-logger/managed-package/
packages/
scripts/
tests/

# NPM
node_modules/
package-lock.json
yarn.lock

# Files to exclude
*.log
*.log
26 changes: 11 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

Designed for Salesforce admins, developers & architects. A robust logger for Apex, Lightning Components, Flow, Process Builder & Integrations.

[![Install Unlocked Package](./content/btn-install-unlocked-package.png)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015khXQAQ)
[![Install Unlocked Package](./content/btn-install-unlocked-package.png)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015klZQAQ)
[![Install Managed Package](./content/btn-install-managed-package.png)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015keOQAQ)
[![View Documentation](./content/btn-view-documentation.png)](https://jongpie.github.io/NebulaLogger/)

Expand All @@ -18,18 +18,19 @@ Designed for Salesforce admins, developers & architects. A robust logger for Ape
3. Leverage `LogEntryEvent__e` platform events for real-time monitoring & integrations
4. Enable logging and set the logging level for different users & profiles using `LoggerSettings__c` custom hierarchy setting
- In addition to the required fields on this Custom Setting record, `LoggerSettings__c` ships with `SystemLogMessageFormat__c`, which uses Handlebars-esque syntax to refer to fields on the `LogEntryEvent__e` Platform Event. You can use curly braces to denote merge field logic, eg: `{OriginLocation__c}\n{Message__c}` - this will output the contents of `LogEntryEvent__e.OriginLocation__c`, a line break, and then the contents of `LogEntryEvent__e.Message__c`
5. View related log entries on any Lighting SObject flexipage by adding the 'Related Log Entries' component in App Builder
6. Dynamically assign tags to `Log__c` and `LogEntry__c` records for tagging/labeling your logs
7. Plugin framework: easily build or install plugins that enhance the `Log__c` and `LogEntry__c` objects, using Apex or Flow (not currently available in the managed package)
8. Event-Driven Integrations with [Platform Events](https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_intro.htm), an event-driven messaging architecture. External integrations can subscribe to log events using the `LogEntryEvent__e` object - see more details at [the Platform Events Developer Guide site](https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_subscribe_cometd.htm)
5. Automatically mask sensitive data by configuring `LogEntryDataMaskRule__mdt` custom metadata rules
6. View related log entries on any Lighting SObject flexipage by adding the 'Related Log Entries' component in App Builder
7. Dynamically assign tags to `Log__c` and `LogEntry__c` records for tagging/labeling your logs
8. Plugin framework: easily build or install plugins that enhance the `Log__c` and `LogEntry__c` objects, using Apex or Flow (not currently available in the managed package)
9. Event-Driven Integrations with [Platform Events](https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_intro.htm), an event-driven messaging architecture. External integrations can subscribe to log events using the `LogEntryEvent__e` object - see more details at [the Platform Events Developer Guide site](https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_subscribe_cometd.htm)

Learn more about the design and history of the project on [Joys Of Apex blog post](https://www.joysofapex.com/advanced-logging-using-nebula-logger/)

---

## Installing

You can choose to install the unlocked package, you can deploy the metadata from this repo to your org, or you can install the managed package. The metadata is the same in all 3 options, but there are some differences in using the 3 versions. All examples in README are for the unlocked package/unpackaged metadata (no namespace) - simply add the `Nebula` namespace from the examples if you are using the managed package.
Nebula Logger is available as both an unlocked package and a managed package. The metadata is the same in both packages, but there are some differences in the available functionality & features. All examples in `README` are for the unlocked package (no namespace) - simply add the `Nebula` namespace to the examples if you are using the managed package.

<table>
<thead>
Expand Down Expand Up @@ -57,22 +58,17 @@ You can choose to install the unlocked package, you can deploy the metadata from
</tr>
<tr>
<td>Apex Debug Statements</td>
<td><code>System.debug()</code> is automatically called - the output can be configured with LoggerSettings__c.SystemLogMessageFormat__c to use any field on LogEntryEvent__e</td>
<td><code>System.debug()</code> is automatically called - the output can be configured with <code>LoggerSettings__c.SystemLogMessageFormat__c</code> to use any field on <code>LogEntryEvent__e</code></td>
<td>Requires adding your own calls for <code>System.debug()</code> due to Salesforce limitations with managed packages</td>
</tr>
<tr>
<td>Apex Stack Traces</td>
<td>Automatically stored in <code>LogEntry__c.StackTrace__c</code> when calling methods like <code>Logger.debug('my message');</code></td>
<td>Requires calling <code>parseStackTrace()</code> due to Salesforce limitations with managed packages. For example:<br><code>Logger.debug('my message').parseStackTrace(new DmlException().getStackTrace());</code></td>
</tr>
<tr>
<td>Assign Topics (Tagging/Labeling System)</td>
<td>Provide <code>List&lt;String&gt; topics</code> in Apex or Flow to dynamically assign Salesforce Topics to <code>Log__c</code> and <code>LogEntry__c</code> records</td>
<td>This functionality is not currently available in the managed package</td>
</tr>
<tr>
<td>Logger Plugin Framework</td>
<td>Leverage Apex or Flow to build your own "plugins" for Logger - to add your own automation to the <code>Log__c</code> or <code>LogEntry__c</code> objects. The logger system will then automatically run your plugins after each trigger event (BEFORE_INSERT, BEFORE_UPDATE, AFTER_INSERT, AFTER_UPDATE, and so on).</td>
<td>Leverage Apex or Flow to build your own "plugins" for Logger - easily add your own automation to the any of the included objects: <code>LogEntryEvent__e</code>, <code>Log__c</code>, <code>LogEntry__c</code>, <code>LogEntryTag__c</code> and <code>LoggerTag__c</code>. The logger system will then automatically run your plugins for each trigger event (BEFORE_INSERT, BEFORE_UPDATE, AFTER_INSERT, AFTER_UPDATE, and so on).</td>
<td>This functionality is not currently available in the managed package</td>
</tr>
</tbody>
Expand All @@ -85,7 +81,7 @@ You can choose to install the unlocked package, you can deploy the metadata from
After deploying Nebula Logger to your org, there are a few additional configuration changes needed...

- Assign permission set(s) to users
- `LoggerLogCreator` provides the minimum access needed for users to generate logs via Apex, Flow or Process Builder
- `LoggerLogCreator` provides the minimum access needed for users to generate logs via Apex, Lightning Components, Flow or Process Builder
- `LoggerEndUser` provides access to generate logs, as well as read-only access to any log records shared with the user.
- `LoggerLogViewer` provides view-all access (read-only) to all log records. This does **not** provide access to generate logs.
- `LoggerAdmin` provides view-all and modify-all access to all log records.
Expand Down Expand Up @@ -336,7 +332,7 @@ Logger.debug('my string').setRecord(currentUser);
Logger.saveLog();
```

### Using LogMessage to Improve CPU Usage for String Formatting
### Using LogMessage for Dynamically-Generated Strings

The class `LogMessage` provides the ability to generate string messages on demand, using `String.format()`. This provides 2 benefits:

Expand Down
2 changes: 2 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ coverage:
threshold: 1%
if_ci_failed: success
patch: off
ignore:
- 'nebula-logger-recipes/**/*'
45 changes: 45 additions & 0 deletions config/pmd-ruleset.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?xml version="1.0" ?>
<ruleset
name="Nebula Logger Rules"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd"
>
<description>
Nebula Logger custom PMD ruleset
</description>
<rule ref="category/apex/bestpractices.xml">
<exclude name="ApexAssertionsShouldIncludeMessage" />
<exclude name="AvoidGlobalModifier" />
<exclude name="AvoidLogicInTrigger" />
</rule>
<rule ref="category/apex/codestyle.xml">
<exclude name="FieldNamingConventions" />
<exclude name="MethodNamingConventions" />
<exclude name="PropertyNamingConventions" />
<exclude name="VariableNamingConventions" />
</rule>
<rule ref="category/apex/design.xml">
<exclude name="AvoidDeeplyNestedIfStmts" />
<exclude name="CognitiveComplexity" />
<exclude name="CyclomaticComplexity" />
<exclude name="ExcessiveClassLength" />
<exclude name="ExcessiveParameterList" />
<exclude name="ExcessivePublicCount" />
<exclude name="NcssConstructorCount" />
<exclude name="NcssMethodCount" />
<exclude name="StdCyclomaticComplexity" />
<exclude name="TooManyFields" />
</rule>
<rule ref="category/apex/documentation.xml">
<exclude name="ApexDoc" />
</rule>
<rule ref="category/apex/errorprone.xml">
<exclude name="EmptyStatementBlock" />
</rule>
<rule ref="category/apex/performance.xml">
<exclude name="AvoidDebugStatements" />
</rule>
<rule ref="category/apex/security.xml">
</rule>
</ruleset>
Loading