Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
9 changes: 5 additions & 4 deletions src/vault-api/core/Reveal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import Client from '../client';
import SkyflowError from '../libs/SkyflowError';
import {
ISkyflowIdRecord, IRevealRecord, IRevealResponseType, IUpdateRecord, IUpdateOptions,
ISkyflowIdRecord, IRevealRecord, IRevealResponseType, IUpdateRecord, IUpdateOptions,RedactionType
} from '../utils/common';
import 'core-js/modules/es.promise.all-settled';
interface IApiSuccessResponse {
Expand Down Expand Up @@ -81,7 +81,7 @@ const getSkyflowIdRecordsFromVault = (
};

const getTokenRecordsFromVault = (
token: string,
tokenRecord: IRevealRecord,
client: Client,
authToken: string,
): Promise<any> => {
Expand All @@ -97,7 +97,8 @@ const getTokenRecordsFromVault = (
{
detokenizationParameters: [
{
token,
token : tokenRecord.token,
redaction: (tokenRecord?.redaction ? tokenRecord.redaction : RedactionType.PLAIN_TEXT)
},
],
},
Expand All @@ -112,7 +113,7 @@ export const fetchRecordsByTokenId = (
const vaultResponseSet: Promise<any>[] = tokenIdRecords.map(
(tokenRecord) => new Promise((resolve) => {
const apiResponse: any = [];
getTokenRecordsFromVault(tokenRecord.token, client, authToken as string)
getTokenRecordsFromVault(tokenRecord, client, authToken as string)
.then(
(response: IApiSuccessResponse) => {
const fieldsData = formatForPureJsSuccess(response);
Expand Down
4 changes: 4 additions & 0 deletions src/vault-api/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ const SKYFLOW_ERROR_CODE = {
INVALID_GET_BY_ID_INPUT:{
code: 400,
description: logs.errorLogs.INVALID_GET_BY_ID_INPUT,
},
DETOKENIZE_INVALID_REDACTION_TYPE:{
code: 400,
description: logs.errorLogs.DETOKENIZE_INVALID_REDACTION_TYPE,
}

};
Expand Down
1 change: 1 addition & 0 deletions src/vault-api/utils/logs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ const logs = {
INVALID_UPDATE_INPUT: 'Interface: update method - Invalid argument , object with records key is required.',
INVALID_RECORDS_UPDATE_INPUT: 'Interface: update method - Invalid records type, records should be an array of objects.',
INVALID_GET_BY_ID_INPUT: 'Interface: getById method - columnName or columnValues cannot be passed, use get method instead.',
DETOKENIZE_INVALID_REDACTION_TYPE:'Interface: detokenize method - Invalid redaction type, use Skyflow.RedactionType enum.',
},
warnLogs: {
GENERATE_BEARER_DEPRECATED: 'This method has been deprecated will be removed in future release, use GenerateBearerToken instead',
Expand Down
6 changes: 6 additions & 0 deletions src/vault-api/utils/validators/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ export const validateDetokenizeInput = (detokenizeInput: IDetokenizeInput) => {
}
if (recordToken === '' || typeof recordToken !== 'string') { throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_TOKEN_ID); }

if (Object.prototype.hasOwnProperty.call(record, 'redaction')) {
if (!Object.values(RedactionType).includes(record.redaction as RedactionType)) {
throw new SkyflowError(SKYFLOW_ERROR_CODE.DETOKENIZE_INVALID_REDACTION_TYPE);
}
}

});
};

Expand Down
308 changes: 308 additions & 0 deletions test/vault-api/Skyflow.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1479,4 +1479,312 @@ describe("Update method",()=>{
});
});

});

describe('skyflow detokenize with redaction', () => {

let skyflow;
beforeEach(() => {
skyflow = Skyflow.init({
vaultID: '<VaultID>',
vaultURL: 'https://www.vaulturl.com',
getBearerToken: jest.fn(),
});
});

test('request body should contains plain text redaction when passed plain text', (done) => {
let reqArg;
const clientReq = jest.fn((arg) => {
reqArg = arg;
return Promise.resolve(detokenizeRes)
});

const mockClient = {
config: skyflowConfig,
request: clientReq,
metadata: {}
}

clientModule.mockImplementation(() => { return mockClient });
skyflow = Skyflow.init({
vaultID: '<VaultID>',
vaultURL: 'https://www.vaulturl.com',
getBearerToken: () => {
return new Promise((resolve, _) => {
resolve("token")
})
}
});

const response = skyflow.detokenize({
records: [
{
token: '123',
redaction: RedactionType.PLAIN_TEXT
}
]
});

response.then(() => {
console.log(reqArg.body);
const tokenRecords = reqArg.body.detokenizationParameters
tokenRecords.forEach((record) => {
expect(record.token).toBe('123');
expect(record.redaction).toBe('PLAIN_TEXT');
})
done();
}).catch((err) => {
done(err);
})


});

test('request body should contains redacted redaction when passed redacted', (done) => {
let reqArg;
const clientReq = jest.fn((arg) => {
reqArg = arg;
return Promise.resolve(detokenizeRes)
});

const mockClient = {
config: skyflowConfig,
request: clientReq,
metadata: {}
}

clientModule.mockImplementation(() => { return mockClient });
skyflow = Skyflow.init({
vaultID: '<VaultID>',
vaultURL: 'https://www.vaulturl.com',
getBearerToken: () => {
return new Promise((resolve, _) => {
resolve("token")
})
}
});

const response = skyflow.detokenize({
records: [
{
token: '123',
redaction: RedactionType.REDACTED
}
]
});

response.then(() => {
console.log(reqArg.body);
const tokenRecords = reqArg.body.detokenizationParameters
tokenRecords.forEach((record) => {
expect(record.token).toBe('123');
expect(record.redaction).toBe('REDACTED');
})
done();
}).catch((err) => {
done(err);
})


});

test('request body should contains masked redaction when passed masked', (done) => {
let reqArg;
const clientReq = jest.fn((arg) => {
reqArg = arg;
return Promise.resolve(detokenizeRes)
});

const mockClient = {
config: skyflowConfig,
request: clientReq,
metadata: {}
}

clientModule.mockImplementation(() => { return mockClient });
skyflow = Skyflow.init({
vaultID: '<VaultID>',
vaultURL: 'https://www.vaulturl.com',
getBearerToken: () => {
return new Promise((resolve, _) => {
resolve("token")
})
}
});

const response = skyflow.detokenize({
records: [
{
token: '123',
redaction: RedactionType.MASKED
}
]
});

response.then(() => {
console.log(reqArg.body);
const tokenRecords = reqArg.body.detokenizationParameters
tokenRecords.forEach((record) => {
expect(record.token).toBe('123');
expect(record.redaction).toBe('MASKED');
})
done();
}).catch((err) => {
done(err);
})


});

test('request body should contains default redaction when passed default', (done) => {
let reqArg;
const clientReq = jest.fn((arg) => {
reqArg = arg;
return Promise.resolve(detokenizeRes)
});

const mockClient = {
config: skyflowConfig,
request: clientReq,
metadata: {}
}

clientModule.mockImplementation(() => { return mockClient });
skyflow = Skyflow.init({
vaultID: '<VaultID>',
vaultURL: 'https://www.vaulturl.com',
getBearerToken: () => {
return new Promise((resolve, _) => {
resolve("token")
})
}
});

const response = skyflow.detokenize({
records: [
{
token: '123',
redaction: RedactionType.DEFAULT
}
]
});

response.then(() => {
console.log(reqArg.body);
const tokenRecords = reqArg.body.detokenizationParameters
tokenRecords.forEach((record) => {
expect(record.token).toBe('123');
expect(record.redaction).toBe('DEFAULT');
})
done();
}).catch((err) => {
done(err);
})


});

test('request body should contains plain text redaction when not passed.', (done) => {
let reqArg;
const clientReq = jest.fn((arg) => {
reqArg = arg;
return Promise.resolve(detokenizeRes)
});

const mockClient = {
config: skyflowConfig,
request: clientReq,
metadata: {}
}

clientModule.mockImplementation(() => { return mockClient });
skyflow = Skyflow.init({
vaultID: '<VaultID>',
vaultURL: 'https://www.vaulturl.com',
getBearerToken: () => {
return new Promise((resolve, _) => {
resolve("token")
})
}
});

const response = skyflow.detokenize({
records: [
{
token: '123',
}
]
});

response.then(() => {
console.log(reqArg.body);
const tokenRecords = reqArg.body.detokenizationParameters
tokenRecords.forEach((record) => {
expect(record.token).toBe('123');
expect(record.redaction).toBe('PLAIN_TEXT');
})
done();
}).catch((err) => {
done(err);
})


});

test('detokenize should throw error when invalid null redaction value is passed.', (done) => {
const response = skyflow.detokenize({
records: [
{
token: '123',
redaction: null
}
]
});

response.then((res) => {
done('should throw error');
}).catch((err) => {
expect(err.errors[0].description).toBe(SKYFLOW_ERROR_CODE.DETOKENIZE_INVALID_REDACTION_TYPE.description);
done();
})

});

test('detokenize should throw error when invalid undefined redaction value is passed.', (done) => {
const response = skyflow.detokenize({
records: [
{
token: '123',
redaction: undefined
}
]
});

response.then((res) => {
done('should throw error');
}).catch((err) => {
expect(err.errors[0].description).toBe(SKYFLOW_ERROR_CODE.DETOKENIZE_INVALID_REDACTION_TYPE.description);
done();
})

});

test('detokenize should throw error when invalid type redaction value is passed.', (done) => {
const response = skyflow.detokenize({
records: [
{
token: '123',
redaction: ''
}
]
});

response.then((res) => {
done('should throw error');
}).catch((err) => {
expect(err.errors[0].description).toBe(SKYFLOW_ERROR_CODE.DETOKENIZE_INVALID_REDACTION_TYPE.description);
done();
})

});
});