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

fix: secret function #3707

Merged
merged 5 commits into from
Jun 30, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
8 changes: 4 additions & 4 deletions docs/helpers/REST.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ I.sendDeleteRequest('/api/users/1');
#### Parameters

- `url` **any**
- `headers` **[object][4]** the headers object to be sent. By default it is sent as an empty object
- `headers` **[object][4]** the headers object to be sent. By default, it is sent as an empty object

Returns **[Promise][2]<any>** response

Expand All @@ -130,7 +130,7 @@ I.sendGetRequest('/api/users.json');
#### Parameters

- `url` **any**
- `headers` **[object][4]** the headers object to be sent. By default it is sent as an empty object
- `headers` **[object][4]** the headers object to be sent. By default, it is sent as an empty object

Returns **[Promise][2]<any>** response

Expand Down Expand Up @@ -167,8 +167,8 @@ I.sendPostRequest('/api/users.json', secret({ "email": "[email protected]" }));
#### Parameters

- `url` **any**
- `payload` **any** the payload to be sent. By default it is sent as an empty object
- `headers` **[object][4]** the headers object to be sent. By default it is sent as an empty object
- `payload` **any** the payload to be sent. By default, it is sent as an empty object
- `headers` **[object][4]** the headers object to be sent. By default, it is sent as an empty object

Returns **[Promise][2]<any>** response

Expand Down
17 changes: 13 additions & 4 deletions lib/helper/REST.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,15 @@ class REST extends Helper {
request.auth = this.headers.auth;
}

if (typeof request.data === 'object') {
let returnedValue = {};
kobenguyent marked this conversation as resolved.
Show resolved Hide resolved
for (const [key, value] of Object.entries(request.data)) {
returnedValue[key] = value;
if (value instanceof Secret) returnedValue[key] = value.getMasked();
}
_debugRequest.data = returnedValue;
}

if (request.data instanceof Secret) {
_debugRequest.data = '*****';
request.data = (typeof request.data === 'object' && !(request.data instanceof Secret)) ? { ...request.data.toString() } : request.data.toString();
Expand Down Expand Up @@ -199,7 +208,7 @@ class REST extends Helper {
* ```
*
* @param {*} url
* @param {object} [headers={}] - the headers object to be sent. By default it is sent as an empty object
* @param {object} [headers={}] - the headers object to be sent. By default, it is sent as an empty object
*
* @returns {Promise<*>} response
*/
Expand All @@ -223,8 +232,8 @@ class REST extends Helper {
* ```
*
* @param {*} url
* @param {*} [payload={}] - the payload to be sent. By default it is sent as an empty object
* @param {object} [headers={}] - the headers object to be sent. By default it is sent as an empty object
* @param {*} [payload={}] - the payload to be sent. By default, it is sent as an empty object
* @param {object} [headers={}] - the headers object to be sent. By default, it is sent as an empty object
*
* @returns {Promise<*>} response
*/
Expand Down Expand Up @@ -318,7 +327,7 @@ class REST extends Helper {
* ```
*
* @param {*} url
* @param {object} [headers={}] - the headers object to be sent. By default it is sent as an empty object
* @param {object} [headers={}] - the headers object to be sent. By default, it is sent as an empty object
*
* @returns {Promise<*>} response
*/
Expand Down
9 changes: 5 additions & 4 deletions lib/secret.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/* eslint-disable max-classes-per-file */
const { deepClone } = require('./utils');

const maskedString = '*****';

/** @param {string} secret */
class Secret {
constructor(secret) {
Expand All @@ -13,7 +15,7 @@ class Secret {
}

getMasked() {
return '*****';
return maskedString;
}

/**
Expand All @@ -36,12 +38,11 @@ function secretObject(obj, fieldsToHide = []) {
if (prop === 'toString') {
return function () {
const maskedObject = deepClone(obj);
fieldsToHide.forEach(f => maskedObject[f] = '****');
fieldsToHide.forEach(f => maskedObject[f] = maskedString);
return JSON.stringify(maskedObject);
};
}

return obj[prop];
return fieldsToHide.includes(prop) ? new Secret(obj[prop]) : obj[prop];
},
};

Expand Down
7 changes: 6 additions & 1 deletion lib/step.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,12 @@ class Step {
} else if (arg.toString && arg.toString() !== '[object Object]') {
return arg.toString();
} else if (typeof arg === 'object') {
return JSON.stringify(arg);
let returnedArg = {};
kobenguyent marked this conversation as resolved.
Show resolved Hide resolved
for (const [key, value] of Object.entries(arg)) {
returnedArg[key] = value;
if (value instanceof Secret) returnedArg[key] = value.getMasked();
}
return JSON.stringify(returnedArg);
}
return arg;
}).join(', ');
Expand Down
11 changes: 6 additions & 5 deletions test/rest/REST_test.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
const path = require('path');
const expect = require('expect');
const fs = require('fs');
const FormData = require('form-data');
const { secret } = require('../../lib/secret');

const TestHelper = require('../support/TestHelper');
const REST = require('../../lib/helper/REST');
const Container = require('../../lib/container');
const Secret = require("../../lib/secret");

const api_url = TestHelper.jsonServerUrl();
global.codeceptjs = require('../../lib');
Expand Down Expand Up @@ -71,15 +72,15 @@ describe('REST', () => {
});

it('should send POST requests with secret', async () => {
const secretData = secret({ name: 'john', password: '123456' }, 'password');
const secretData = Secret.secret({ name: 'john', password: '123456' }, 'password');
const response = await I.sendPostRequest('/user', secretData);
response.data.name.should.eql('john');
response.data.password.should.eql('123456');
secretData.toString().should.include('"password":"****"');
expect(response.data.password).toEqual({ _secret: '123456' });
expect(secretData.password.getMasked()).toEqual('*****');
});

it('should send POST requests with secret form encoded is not converted to string', async () => {
const secretData = secret('name=john&password=123456');
const secretData = Secret.secret('name=john&password=123456');
const response = await I.sendPostRequest('/user', secretData);
response.data.name.should.eql('john');
response.data.password.should.eql('123456');
Expand Down
19 changes: 19 additions & 0 deletions test/unit/secret_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const expect = require('expect');
const Secret = require('../../lib/secret');

describe('Secret tests', () => {
it('should be the Secret instance', () => {
const string = Secret.secret('hello');
expect(string).toBeInstanceOf(Secret);
});

it('should be the Secret instance when using as object', () => {
const obj = Secret.secret({ password: 'world' }, 'password');
expect(obj.password).toBeInstanceOf(Secret);
});

it('should mask the field when provided', () => {
const obj = Secret.secret({ password: 'world' }, 'password');
expect(obj.password.getMasked()).toBe('*****');
});
});
Loading