Skip to content

Commit b526f48

Browse files
[TECH] Suppression du token d’accès aux résultats de campagne (PIX-16610)
#11443
2 parents 38e7a7b + 9aed4ff commit b526f48

File tree

11 files changed

+3
-108
lines changed

11 files changed

+3
-108
lines changed

Diff for: api/sample.env

-6
Original file line numberDiff line numberDiff line change
@@ -706,12 +706,6 @@ REFRESH_TOKEN_LIFESPAN=7d
706706
# default: '7d'
707707
SAML_ACCESS_TOKEN_LIFESPAN=7d
708708

709-
# Campaign result access token lifespan
710-
# presence: optional
711-
# type: string
712-
# default: 1h
713-
#CAMPAIGN_RESULT_ACCESS_TOKEN_LIFESPAN=
714-
715709
# ========
716710
# TESTS
717711
# ========

Diff for: api/src/prescription/campaign/application/campaign-detail-controller.js

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import stream from 'node:stream';
22

3-
import { tokenService } from '../../../shared/domain/services/token-service.js';
43
import { extractLocaleFromRequest } from '../../../shared/infrastructure/utils/request-response-utils.js';
54
import { escapeFileName } from '../../../shared/infrastructure/utils/request-response-utils.js';
65
import { usecases } from '../domain/usecases/index.js';
@@ -31,16 +30,13 @@ const getById = async function (
3130
_,
3231
dependencies = {
3332
campaignReportSerializer,
34-
tokenService,
3533
},
3634
) {
3735
const { userId } = request.auth.credentials;
3836
const { campaignId } = request.params;
3937

40-
const tokenForCampaignResults = dependencies.tokenService.createTokenForCampaignResults({ userId, campaignId });
41-
4238
const campaign = await usecases.getCampaign({ campaignId, userId });
43-
return dependencies.campaignReportSerializer.serialize(campaign, {}, { tokenForCampaignResults });
39+
return dependencies.campaignReportSerializer.serialize(campaign);
4440
};
4541

4642
const getCampaignDetails = async function (request) {

Diff for: api/src/prescription/campaign/infrastructure/serializers/jsonapi/campaign-report-serializer.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@ import jsonapiSerializer from 'jsonapi-serializer';
22

33
const { Serializer } = jsonapiSerializer;
44

5-
const serialize = function (campaignReports, meta, { tokenForCampaignResults } = {}) {
5+
const serialize = function (campaignReports, meta) {
66
return new Serializer('campaign', {
77
transform: (record) => {
88
const campaign = Object.assign({}, record);
9-
campaign.tokenForCampaignResults = tokenForCampaignResults;
109
campaign.isArchived = record.isArchived;
1110
return campaign;
1211
},
@@ -18,7 +17,6 @@ const serialize = function (campaignReports, meta, { tokenForCampaignResults } =
1817
'createdAt',
1918
'customLandingPageText',
2019
'isArchived',
21-
'tokenForCampaignResults',
2220
'externalIdLabel',
2321
'externalIdType',
2422
'targetProfileId',

Diff for: api/src/shared/config.js

-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,6 @@ const configuration = (function () {
224224
accessTokenLifespanMs: ms(process.env.ACCESS_TOKEN_LIFESPAN || '20m'),
225225
refreshTokenLifespanMs: ms(process.env.REFRESH_TOKEN_LIFESPAN || '7d'),
226226
revokedUserAccessLifespanMs: ms(process.env.REVOKED_USER_ACCESS_LIFESPAN || '7d'),
227-
tokenForCampaignResultLifespan: process.env.CAMPAIGN_RESULT_ACCESS_TOKEN_LIFESPAN || '1h',
228227
tokenForStudentReconciliationLifespan: '1h',
229228
passwordResetTokenLifespan: '1h',
230229
},

Diff for: api/src/shared/config.maddo.js

-1
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,6 @@ const configuration = (function () {
168168
'pix-admin': ms(process.env.REFRESH_TOKEN_LIFESPAN_PIX_ADMIN || '7d'),
169169
},
170170
revokedUserAccessLifespanMs: ms(process.env.REVOKED_USER_ACCESS_LIFESPAN || '7d'),
171-
tokenForCampaignResultLifespan: process.env.CAMPAIGN_RESULT_ACCESS_TOKEN_LIFESPAN || '1h',
172171
tokenForStudentReconciliationLifespan: '1h',
173172
passwordResetTokenLifespan: '1h',
174173
},

Diff for: api/src/shared/domain/services/token-service.js

-24
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import jsonwebtoken from 'jsonwebtoken';
22

33
import { config } from '../../../../src/shared/config.js';
44
import {
5-
ForbiddenAccess,
65
InvalidExternalUserTokenError,
76
InvalidResultRecipientTokenError,
87
InvalidSessionResultTokenError,
@@ -51,17 +50,6 @@ function createAccessTokenFromApplication(
5150
);
5251
}
5352

54-
function createTokenForCampaignResults({ userId, campaignId }) {
55-
return jsonwebtoken.sign(
56-
{
57-
access_id: userId,
58-
campaign_id: campaignId,
59-
},
60-
config.authentication.secret,
61-
{ expiresIn: config.authentication.tokenForCampaignResultLifespan },
62-
);
63-
}
64-
6553
function createIdTokenForUserReconciliation(externalUser) {
6654
return jsonwebtoken.sign(
6755
{
@@ -187,14 +175,6 @@ function extractClientId(token, secret = config.authentication.secret) {
187175
return decoded.client_id || null;
188176
}
189177

190-
function extractCampaignResultsTokenContent(token) {
191-
const decoded = getDecodedToken(token);
192-
if (decoded === false) {
193-
throw new ForbiddenAccess();
194-
}
195-
return { userId: decoded.access_id, campaignId: decoded.campaign_id };
196-
}
197-
198178
async function extractExternalUserFromIdToken(token) {
199179
const externalUser = await getDecodedToken(token);
200180

@@ -215,7 +195,6 @@ const tokenService = {
215195
createAccessTokenForSaml,
216196
createAccessTokenFromApplication,
217197
createAccessTokenFromAnonymousUser,
218-
createTokenForCampaignResults,
219198
createIdTokenForUserReconciliation,
220199
createCertificationResultsByRecipientEmailLinkToken,
221200
createCertificationResultsLinkToken,
@@ -229,7 +208,6 @@ const tokenService = {
229208
extractTokenFromAuthChain,
230209
extractUserId,
231210
extractClientId,
232-
extractCampaignResultsTokenContent,
233211
};
234212

235213
/**
@@ -245,9 +223,7 @@ export {
245223
createCertificationResultsLinkToken,
246224
createIdTokenForUserReconciliation,
247225
createPasswordResetToken,
248-
createTokenForCampaignResults,
249226
decodeIfValid,
250-
extractCampaignResultsTokenContent,
251227
extractCertificationResultsByRecipientEmailLink,
252228
extractCertificationResultsLink,
253229
extractClientId,

Diff for: api/tests/prescription/campaign/unit/application/campaign-detail-controller_test.js

+1-8
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ describe('Unit | Application | Controller | Campaign detail', function () {
3939

4040
let request, campaign;
4141
let campaignReportSerializerStub;
42-
let tokenServiceStub;
4342

4443
beforeEach(function () {
4544
campaign = {
@@ -62,28 +61,22 @@ describe('Unit | Application | Controller | Campaign detail', function () {
6261
campaignReportSerializerStub = {
6362
serialize: sinon.stub(),
6463
};
65-
tokenServiceStub = { createTokenForCampaignResults: sinon.stub().returns('token') };
6664
usecases.getCampaign.resolves(campaign);
6765
});
6866

6967
it('should return the campaign', async function () {
7068
// given
7169
const expectedResult = Symbol('ok');
72-
const tokenForCampaignResults = 'token';
73-
campaignReportSerializerStub.serialize
74-
.withArgs(campaign, {}, { tokenForCampaignResults })
75-
.returns(expectedResult);
70+
campaignReportSerializerStub.serialize.withArgs(campaign).returns(expectedResult);
7671

7772
const dependencies = {
7873
campaignReportSerializer: campaignReportSerializerStub,
79-
tokenService: tokenServiceStub,
8074
};
8175
// when
8276
const response = await campaignDetailController.getById(request, hFake, dependencies);
8377

8478
// then
8579
expect(usecases.getCampaign).calledWith({ campaignId, userId });
86-
expect(tokenServiceStub.createTokenForCampaignResults).to.have.been.calledWithExactly({ userId, campaignId });
8780
expect(response).to.deep.equal(expectedResult);
8881
});
8982
});

Diff for: api/tests/prescription/campaign/unit/infrastructure/serializers/jsonapi/campaign-report-serializer_test.js

-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ describe('Unit | Serializer | JSONAPI | campaign-report-serializer', function ()
112112
'target-profile-tubes-count': report.targetProfileTubesCount,
113113
'target-profile-thematic-result-count': report.targetProfileThematicResultCount,
114114
'target-profile-are-knowledge-elements-resettable': report.targetProfileAreKnowledgeElementsResettable,
115-
'token-for-campaign-results': report.tokenForCampaignResults,
116115
'participations-count': report.participationsCount,
117116
'shared-participations-count': report.sharedParticipationsCount,
118117
'average-result': report.averageResult,

Diff for: api/tests/shared/unit/domain/services/token-service_test.js

-56
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import jsonwebtoken from 'jsonwebtoken';
44

55
import { config, config as settings } from '../../../../../src/shared/config.js';
66
import {
7-
ForbiddenAccess,
87
InvalidExternalUserTokenError,
98
InvalidResultRecipientTokenError,
109
InvalidSessionResultTokenError,
@@ -14,32 +13,6 @@ import { tokenService } from '../../../../../src/shared/domain/services/token-se
1413
import { catchErr, expect, sinon } from '../../../../test-helper.js';
1514

1615
describe('Unit | Shared | Domain | Services | Token Service', function () {
17-
describe('#createTokenForCampaignResults', function () {
18-
it('should create an access token with user id and campaign id', function () {
19-
// given
20-
const generatedAccessToken = 'Valid-Access-Token';
21-
const userId = 123;
22-
const campaignId = 456;
23-
24-
sinon.stub(settings.authentication, 'secret').value('a secret');
25-
sinon.stub(settings.authentication, 'tokenForCampaignResultLifespan').value(10);
26-
sinon.stub(jsonwebtoken, 'sign').returns(generatedAccessToken);
27-
28-
// when
29-
const accessTokenForCampaignResults = tokenService.createTokenForCampaignResults({ userId, campaignId });
30-
31-
// then
32-
expect(accessTokenForCampaignResults).to.equal(generatedAccessToken);
33-
expect(jsonwebtoken.sign).to.have.been.calledWithExactly(
34-
{ access_id: userId, campaign_id: campaignId },
35-
'a secret',
36-
{
37-
expiresIn: 10,
38-
},
39-
);
40-
});
41-
});
42-
4316
describe('#createAccessTokenFromUser', function () {
4417
it('should create access token with user id and source', function () {
4518
// given
@@ -169,35 +142,6 @@ describe('Unit | Shared | Domain | Services | Token Service', function () {
169142
});
170143
});
171144

172-
describe('#extractCampaignResultsTokenContent', function () {
173-
context('valid token', function () {
174-
it('should return userId and campaignId if the accessToken is valid', function () {
175-
// given
176-
const accessToken = tokenService.createTokenForCampaignResults({ userId: 123, campaignId: 456 });
177-
178-
// when
179-
const { userId, campaignId } = tokenService.extractCampaignResultsTokenContent(accessToken);
180-
181-
// then
182-
expect(userId).to.equal(123);
183-
expect(campaignId).to.equal(456);
184-
});
185-
});
186-
187-
context('invalid token', function () {
188-
it('should return null', async function () {
189-
// given
190-
const accessToken = 'WRONG_DATA';
191-
192-
// when
193-
const error = await catchErr(tokenService.extractCampaignResultsTokenContent)(accessToken);
194-
195-
// then
196-
expect(error).to.be.an.instanceof(ForbiddenAccess);
197-
});
198-
});
199-
});
200-
201145
describe('#decodeIfValid', function () {
202146
it('should throw an Invalid token error, when token is not valid', async function () {
203147
// given

Diff for: orga/app/models/campaign.js

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ export default class Campaign extends Model {
1414
@attr('nullable-string') externalIdLabel;
1515
@attr('string') externalIdType;
1616
@attr('nullable-text') customLandingPageText;
17-
@attr('string') tokenForCampaignResults;
1817
@attr('number') ownerId;
1918
@attr('string') ownerLastName;
2019
@attr('string') ownerFirstName;

Diff for: orga/tests/unit/models/campaign-test.js

-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ module('Unit | Model | campaign', function (hooks) {
2323
id: '1',
2424
name: 'Fake name',
2525
code: 'ABC123',
26-
tokenForCampaignResults: 'token',
2726
type: 'ASSESSMENT',
2827
});
2928
assert.strictEqual(model.urlToResult, 'http://localhost:3000/api/campaigns/1/csv-assessment-results');
@@ -35,7 +34,6 @@ module('Unit | Model | campaign', function (hooks) {
3534
id: '1',
3635
name: 'Fake name',
3736
code: 'ABC123',
38-
tokenForCampaignResults: 'token',
3937
type: 'PROFILES_COLLECTION',
4038
});
4139
assert.strictEqual(model.urlToResult, 'http://localhost:3000/api/campaigns/1/csv-profiles-collection-results');

0 commit comments

Comments
 (0)