Skip to content

Commit

Permalink
Dropped support for legacy restricted use token validation - #70
Browse files Browse the repository at this point in the history
  • Loading branch information
tiblu committed Sep 24, 2019
1 parent f6ec565 commit d885411
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 155 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
## 2019-09-24
* Dropped support for legacy restricted use token validation - https://github.com/citizenos/citizenos-api/issues/70

## 2019-08-02

* Log user ip-s into acitivities table https://github.com/citizenos/citizenos-api/issues/133
* Log user ip-s into activities table (Law enforcement) - https://github.com/citizenos/citizenos-api/issues/133

## 2019-07-19

Expand Down
35 changes: 2 additions & 33 deletions libs/cosJwt.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,40 +70,9 @@ module.exports = function (app) {
var _verifyTokenRestrictedUse = function (token, audience, options) {
var effectiveOptions = Object.assign({}, TOKEN_OPTIONS_VERIFY_DEFAULTS, options);

//eslint-disable-next-line
/** TODO: Uncomment this block when legacy token support is dropped! - https://github.com/citizenos/citizenos-api/issues/70
effectiveOptions.audience = audience;
effectiveOptions.audience = audience;

return jwt.verify(token, config.session.publicKey, effectiveOptions);
*/

// TODO: Delete all below this when you uncomment the block above and drop the legacy token support! - https://github.com/citizenos/citizenos-api/issues/70
// NOTE: While legacy token with (path/paths) verification is required, not using jwt.verify-s audience option to verify the audience.
// When legacy token support is removed, can use "effectiveOptions.audience = audience;" and delete the whole manual verification code.
var decoded = jwt.verify(token, config.session.publicKey, effectiveOptions);

if (decoded.path) { // Let's see if its a legacy token with "path" string property containing path without method. Example: "/foo/bar"
if (decoded.path === audience.split(' ')[1]) {
return decoded;
} else {
throw new jwt.JsonWebTokenError('jwt audience invalid. expected: ' + audience);
}
} else if (decoded.paths) { // Let's see if its a legacy token with "paths" array property with path and method. Example: "['GET_/foo/bar']"
if (decoded.paths.indexOf(audience.replace(' ', '_')) > -1) {
return decoded;
} else {
throw new jwt.JsonWebTokenError('jwt audience invalid. expected: ' + audience);
}
} else if (decoded.aud) { // The right format by the JWT standard "aud" containing paths with methods separated by space.
if (decoded.aud.indexOf(audience) > -1) {
return decoded;
} else {
throw new jwt.JsonWebTokenError('jwt audience invalid. expected: ' + audience);
}
} else {
// No audience (scope) provided, we don't like that...
throw new jwt.JsonWebTokenError('jwt audience missing. expected: ' + audience);
}
return jwt.verify(token, config.session.publicKey, effectiveOptions);
};

return {
Expand Down
95 changes: 24 additions & 71 deletions test/api/topic.js
Original file line number Diff line number Diff line change
Expand Up @@ -10074,48 +10074,6 @@ suite('Topics', function () {
});
});

test('Success - legacy token with "paths"', function (done) {
var token = jwt.sign(
{
paths: [
'GET_/api/topics/:topicId/comments/:commentId/reports/:reportId'
.replace(':topicId', topic.id)
.replace(':commentId', comment.id)
.replace(':reportId', report.id)
],
userId: userModerator.id
},
config.session.privateKey,
{
algorithm: config.session.algorithm
}
);

topicCommentReportRead(request.agent(app), topic.id, comment.id, report.id, token, function (err, res) {
if (err) return done(err);

var expectedResult = {
status: {code: 20000},
data: {
id: report.id,
type: report.type,
text: report.text,
createdAt: report.createdAt,
comment: {
subject: comment.subject,
text: comment.text,
id: comment.id
}
}
};

assert.deepEqual(res.body, expectedResult);

done();
});
});


test('Fail - 40100 - Invalid token', function (done) {
var token = {};
_topicCommentReportRead(request.agent(app), topic.id, comment.id, report.id, token, 401, done);
Expand Down Expand Up @@ -10251,20 +10209,16 @@ suite('Topics', function () {
var moderateType = Comment.DELETE_REASON_TYPES.duplicate;
var moderateText = 'Report create moderation text';

var token = jwt.sign(
var token = cosJwt.getTokenRestrictedUse(
{
paths: [
'POST_/api/topics/:topicId/comments/:commentId/reports/:reportId/moderate'
.replace(':topicId', topic.id)
.replace(':commentId', comment.id)
.replace(':reportId', report.id)
],
userId: userModerator.id
},
config.session.privateKey,
{
algorithm: config.session.algorithm
}
[
'POST /api/topics/:topicId/comments/:commentId/reports/:reportId/moderate'
.replace(':topicId', topic.id)
.replace(':commentId', comment.id)
.replace(':reportId', report.id)
]
);

topicCommentReportModerate(request.agent(app), topic.id, comment.id, report.id, token, moderateType, moderateText, function (err) {
Expand Down Expand Up @@ -10340,20 +10294,16 @@ suite('Topics', function () {
var moderateType = Comment.DELETE_REASON_TYPES.duplicate;
var moderateText = 'Report create moderation text';

var token = jwt.sign(
var token = cosJwt.getTokenRestrictedUse(
{
paths: [
'POST_/api/topics/:topicId/comments/:commentId/reports/:reportId/moderate'
.replace(':topicId', topic.id)
.replace(':commentId', comment.id)
.replace(':reportId', report.id)
],
userId: userModerator.id
},
config.session.privateKey,
{
algorithm: config.session.algorithm
}
[
'POST /api/topics/:topicId/comments/:commentId/reports/:reportId/moderate'
.replace(':topicId', topic.id)
.replace(':commentId', comment.id)
.replace(':reportId', report.id)
]
);

Comment
Expand Down Expand Up @@ -10736,13 +10686,16 @@ suite('Topics', function () {
var subject = 'Test Event title, testing with token';
var text = 'Test Event description, testing with token';

var path = '/api/topics/:topicId/events'
.replace(':topicId', topic.id);

var token = jwt.sign({path: path}, config.session.privateKey, {
expiresIn: '1d',
algorithm: config.session.algorithm
});
var token = cosJwt.getTokenRestrictedUse(
{},
[
'POST /api/topics/:topicId/events'
.replace(':topicId', topic.id)
],
{
expiresIn: '1d'
}
);

topicEventCreateUnauth(agent, topic.id, token, subject, text, function (err, res) {
if (err) return done(err);
Expand Down
51 changes: 1 addition & 50 deletions test/libs/cosJwt.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,55 +21,6 @@ suite('cosJwt', function () {
done();
});

test('Success - legacy token "path" string without a method. Example: "/foo/bar"', function (done) {
var testAudience = 'GET /foo/bar';
var testAudienceLegacy = testAudience.split(' ')[1];

var testPayload = {
foo: 'bar',
path: testAudienceLegacy
};

var token = jwt.sign(
testPayload,
config.session.privateKey,
{
algorithm: config.session.algorithm
}
);

var decoded = cosJwt.verifyTokenRestrictedUse(token, testAudience);

assert.equal(decoded.foo, testPayload.foo);
assert.deepEqual(decoded.path, testAudienceLegacy);

done();
});

test('Success - legacy token "paths" array without a method. Example: "[\'GET_/foo/bar\']"', function (done) {
var testAudience = 'GET /api/foo/bar';
var testAudienceLegacy = testAudience.replace(' ', '_');
var testPayload = {
foo: 'bar',
paths: [testAudienceLegacy]
};

var token = jwt.sign(
testPayload,
config.session.privateKey,
{
algorithm: config.session.algorithm
}
);

var decoded = cosJwt.verifyTokenRestrictedUse(token, testAudience);

assert.equal(decoded.foo, testPayload.foo);
assert.deepEqual(decoded.paths, [testAudienceLegacy]);

done();
});

test('Success - multiple audiences (scopes)', function (done) {
var testPayload = {foo: 'bar'};
var testAudiences = ['GET /asd', 'POST /api/foo/bar'];
Expand Down Expand Up @@ -168,7 +119,7 @@ suite('cosJwt', function () {
return done(new Error('Should fail due to invalid audience!'));
} catch (err) {
assert.instanceOf(err, jwt.JsonWebTokenError);
assert.equal(err.message, 'jwt audience missing. expected: ' + testAudience);
assert.equal(err.message, 'jwt audience invalid. expected: ' + testAudience);

done();
}
Expand Down

0 comments on commit d885411

Please sign in to comment.