Skip to content

Commit f1a07a7

Browse files
authored
Add setSanitizedResult function (#1022)
1 parent e141f49 commit f1a07a7

7 files changed

+79
-2
lines changed

node/internal.ts

+14
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ export function _endsWith(str: string, end: string): boolean {
4949
return str.slice(-end.length) == end;
5050
}
5151

52+
export function _truncateBeforeSensitiveKeyword(str: string, sensitiveKeywordsPattern: RegExp): string {
53+
if(!str) {
54+
return str;
55+
}
56+
57+
const index = str.search(sensitiveKeywordsPattern);
58+
59+
if (index <= 0) {
60+
return str;
61+
}
62+
63+
return `${str.substring(0, index)}...`;
64+
}
65+
5266
//-----------------------------------------------------
5367
// General Helpers
5468
//-----------------------------------------------------

node/mock-task.ts

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ module.exports.Platform = task.Platform;
3131
module.exports.setStdStream = task.setStdStream;
3232
module.exports.setErrStream = task.setErrStream;
3333
module.exports.setResult = task.setResult;
34+
module.exports.setSanitizedResult = task.setSanitizedResult;
3435

3536
//-----------------------------------------------------
3637
// Loc Helpers

node/package-lock.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "azure-pipelines-task-lib",
3-
"version": "4.9.0",
3+
"version": "4.9.1",
44
"description": "Azure Pipelines Task SDK",
55
"main": "./task.js",
66
"typings": "./task.d.ts",

node/task.ts

+18
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,24 @@ export function setResult(result: TaskResult, message: string, done?: boolean):
104104
command('task.complete', properties, message);
105105
}
106106

107+
/**
108+
* Sets the result of the task with sanitized message.
109+
*
110+
* @param result TaskResult enum of Succeeded, SucceededWithIssues, Failed, Cancelled or Skipped.
111+
* @param message A message which will be logged as an error issue if the result is Failed. Message will be truncated
112+
* before first occurence of wellknown sensitive keyword.
113+
* @param done Optional. Instructs the agent the task is done. This is helpful when child processes
114+
* may still be running and prevent node from fully exiting. This argument is supported
115+
* from agent version 2.142.0 or higher (otherwise will no-op).
116+
* @returns void
117+
*/
118+
119+
export function setSanitizedResult(result: TaskResult, message: string, done?: boolean): void {
120+
const pattern = /password|key|secret|bearer|authorization|token|pat/i;
121+
const sanitizedMessage = im._truncateBeforeSensitiveKeyword(message, pattern);
122+
setResult(result, sanitizedMessage, done);
123+
}
124+
107125
//
108126
// Catching all exceptions
109127
//

node/test/internalhelpertests.ts

+27
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,33 @@ import * as tl from '../_build/task';
99
import * as im from '../_build/internal';
1010
import * as mockery from '../_build/lib-mocker'
1111

12+
describe('Internal String Helper Tests: _truncateBeforeSensitiveKeyword', function () {
13+
14+
it('truncates before known sensitive keywords', () => {
15+
const input = "this is a secret password";
16+
17+
const result = im._truncateBeforeSensitiveKeyword(input, /secret/i);
18+
19+
assert.strictEqual(result, "this is a ...");
20+
});
21+
22+
it('does not truncate without sensitive keyword', () => {
23+
const input = "this is a secret password";
24+
25+
const result = im._truncateBeforeSensitiveKeyword(input, /key/i);
26+
27+
assert.strictEqual(result, input);
28+
});
29+
30+
it('process undefined gracefully', () => {
31+
const input: string = undefined;
32+
33+
const result = im._truncateBeforeSensitiveKeyword(input, /key/i);
34+
35+
assert.strictEqual(result, input);
36+
});
37+
});
38+
1239
describe('Internal Path Helper Tests', function () {
1340

1441
before(function (done) {

node/test/resulttests.ts

+17
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,23 @@ describe('Result Tests', function () {
106106

107107
assert.equal(output, expected);
108108

109+
done();
110+
})
111+
it('setSanitizedResult success outputs', function (done) {
112+
this.timeout(1000);
113+
114+
var stdStream = testutil.createStringStream();
115+
tl.setStdStream(stdStream);
116+
tl.setSanitizedResult(tl.TaskResult.Succeeded, 'success msg with secret data');
117+
118+
var expected = testutil.buildOutput(
119+
['##vso[task.debug]task result: Succeeded',
120+
'##vso[task.complete result=Succeeded;]success msg with ...']);
121+
122+
var output = stdStream.getContents();
123+
124+
assert.equal(output, expected);
125+
109126
done();
110127
})
111128
});

0 commit comments

Comments
 (0)