Modified Admin API key output format

refs #9865

- Changed key format to {id}:{secret} so API consumer only has to worry about copying a single value during setup
- Updated key expiration time in getValidAdminToken test helper to match server side expiration check
This commit is contained in:
Nazar Gargol 2019-01-23 17:08:57 +00:00
parent 776e23696d
commit 5fbad09a56
6 changed files with 79 additions and 4 deletions

View File

@ -1,11 +1,12 @@
const debug = require('ghost-ignition').debug('api:v2:utils:serializers:output:integrations');
const mapper = require('./utils/mapper');
module.exports = {
browse({data, meta}, apiConfig, frame) {
debug('browse');
frame.response = {
integrations: data.map(model => model.toJSON(frame.options)),
integrations: data.map(model => mapper.mapIntegration(model, frame)),
meta
};
},
@ -13,21 +14,21 @@ module.exports = {
debug('read');
frame.response = {
integrations: [model.toJSON(frame.options)]
integrations: [mapper.mapIntegration(model, frame)]
};
},
add(model, apiConfig, frame) {
debug('add');
frame.response = {
integrations: [model.toJSON(frame.options)]
integrations: [mapper.mapIntegration(model, frame)]
};
},
edit(model, apiConfig, frame) {
debug('edit');
frame.response = {
integrations: [model.toJSON(frame.options)]
integrations: [mapper.mapIntegration(model, frame)]
};
}
};

View File

@ -76,7 +76,22 @@ const mapSettings = (attrs) => {
return attrs;
};
const mapIntegration = (model, frame) => {
const jsonModel = model.toJSON ? model.toJSON(frame.options) : model;
if (jsonModel.api_keys) {
jsonModel.api_keys.forEach((key) => {
if (key.type === 'admin') {
key.secret = `${key.id}:${key.secret}`;
}
});
}
return jsonModel;
};
module.exports.mapPost = mapPost;
module.exports.mapUser = mapUser;
module.exports.mapTag = mapTag;
module.exports.mapIntegration = mapIntegration;
module.exports.mapSettings = mapSettings;

View File

@ -50,6 +50,14 @@ describe('Integrations API', function () {
const adminApiKey = integration.api_keys.find(findBy('type', 'admin'));
should.equal(adminApiKey.integration_id, integration.id);
should.exist(adminApiKey.secret);
// check Admin API key secret format
const [id, secret] = adminApiKey.secret.split(':');
should.exist(id);
should.equal(id, adminApiKey.id);
should.exist(secret);
secret.length.should.equal(128);
done();
});

View File

@ -105,6 +105,7 @@ module.exports = {
const jwt = require('jsonwebtoken');
const JWT_OPTIONS = {
algorithm: 'HS256',
expiresIn: '5m',
audience: endpoint
};

View File

@ -168,4 +168,39 @@ describe('Unit: v2/utils/serializers/output/utils/mapper', () => {
urlUtil.forTag.getCall(0).args.should.eql(['id3', tag]);
});
});
describe('mapIntegration', () => {
let integrationModel;
beforeEach(() => {
integrationModel = (data) => {
return Object.assign(data, {toJSON: sinon.stub().returns(data)});
};
});
it('formats admin keys', () => {
const frame = {
};
const integration = integrationModel(testUtils.DataGenerator.forKnex.createIntegration({
api_keys: testUtils.DataGenerator.Content.api_keys
}));
const mapped = mapper.mapIntegration(integration, frame);
should.exist(mapped.api_keys);
mapped.api_keys.forEach(key => {
if (key.type === 'admin') {
const [id, secret] = key.secret.split(':');
should.exist(id);
should.exist(secret);
} else {
const [id, secret] = key.secret.split(':');
should.exist(id);
should.not.exist(secret);
}
});
});
});
});

View File

@ -674,6 +674,20 @@ DataGenerator.forKnex = (function () {
});
}
function createIntegration(overrides) {
var newObj = _.cloneDeep(overrides);
return _.defaults(newObj, {
id: ObjectId.generate(),
name: 'test integration',
slug: 'test-integration',
created_by: DataGenerator.Content.users[0].id,
created_at: new Date(),
updated_by: DataGenerator.Content.users[0].id,
updated_at: new Date()
});
}
const posts = [
createPost(DataGenerator.Content.posts[0]),
createPost(DataGenerator.Content.posts[1]),
@ -902,6 +916,7 @@ DataGenerator.forKnex = (function () {
createInvite: createInvite,
createTrustedDomain: createTrustedDomain,
createWebhook: createWebhook,
createIntegration: createIntegration,
invites: invites,
posts: posts,