Skip to content

Commit

Permalink
feat(api): save last user application connection in #authenticateOidc…
Browse files Browse the repository at this point in the history
…User
  • Loading branch information
P-Jeremy committed Feb 27, 2025
1 parent 132dd0b commit 11b363c
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { getForwardedOrigin, RequestedApplication } from '../../infrastructure/u
async function authenticateOidcUser(request, h) {
const { code, state, iss, identityProvider: identityProviderCode, target } = request.deserializedPayload;
const origin = getForwardedOrigin(request.headers);
const requestedApplication = RequestedApplication.fromOrigin(origin);

const sessionState = request.yar.get('state', true);
const nonce = request.yar.get('nonce', true);
Expand All @@ -32,6 +33,7 @@ async function authenticateOidcUser(request, h) {
nonce,
sessionState,
audience: origin,
requestedApplication,
});

if (result.isAuthenticationComplete) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import { ForbiddenAccess } from '../../../shared/domain/errors.js';
* @param {AuthenticationMethodRepository} params.authenticationMethodRepository
* @param {UserLoginRepository} params.userLoginRepository
* @param {UserRepository} params.userRepository
* @param {LastUserApplicationConnectionsRepository} params.LastUserApplicationConnectionsRepository,
* @param {RequestedApplication} params.RequestedApplication,
* @return {Promise<{isAuthenticationComplete: boolean, givenName: string, familyName: string, authenticationKey: string, email: string}|{isAuthenticationComplete: boolean, pixAccessToken: string, logoutUrlUUID: string}>}
*/
async function authenticateOidcUser({
Expand All @@ -34,6 +36,8 @@ async function authenticateOidcUser({
authenticationMethodRepository,
userLoginRepository,
userRepository,
lastUserApplicationConnectionsRepository,
requestedApplication,
}) {
await oidcAuthenticationServiceRegistry.loadOidcProviderServices();
await oidcAuthenticationServiceRegistry.configureReadyOidcProviderServiceByCode(identityProviderCode);
Expand Down Expand Up @@ -86,6 +90,11 @@ async function authenticateOidcUser({
}

await userLoginRepository.updateLastLoggedAt({ userId: user.id });
await lastUserApplicationConnectionsRepository.upsert({
userId: user.id,
application: requestedApplication.applicationName,
lastLoggedAt: new Date(),
});

return { pixAccessToken, logoutUrlUUID, isAuthenticationComplete: true };
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,14 @@ describe('Acceptance | Identity Access Management | Application | Route | oidc-p
lastName: 'Doe',
},
};
const headers = generateAuthenticatedUserRequestHeaders();
headers.cookie = cookies[0];

// when
const response = await server.inject({
method: 'POST',
url: '/api/oidc/token',
headers: { cookie: cookies[0] },
headers,
payload,
});

Expand Down Expand Up @@ -331,11 +333,14 @@ describe('Acceptance | Identity Access Management | Application | Route | oidc-p
// const getAccessTokenRequest = nock(settings.poleEmploi.tokenUrl).post('/').reply(200, getAccessTokenResponse);
oidcExampleNetProvider.client.callback.resolves(getAccessTokenResponse);

const headers = generateAuthenticatedUserRequestHeaders();
headers.cookie = cookies[0];

// when
const response = await server.inject({
method: 'POST',
url: '/api/oidc/token',
headers: { cookie: cookies[0] },
headers,
payload,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ describe('Unit | Identity Access Management | Application | Controller | oidc-pr
const identityProvider = 'OIDC_EXAMPLE_NET';
const pixAccessToken = 'pixAccessToken';
const audience = 'https://app.pix.fr';
const requestedApplication = new RequestedApplication('app');

let request;

Expand Down Expand Up @@ -60,6 +61,7 @@ describe('Unit | Identity Access Management | Application | Controller | oidc-pr
state: identityProviderState,
iss,
audience,
requestedApplication,
});
expect(request.yar.commit).to.have.been.calledOnce;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as appMessages from '../../../../../src/authorization/domain/constants.
import { POLE_EMPLOI } from '../../../../../src/identity-access-management/domain/constants/oidc-identity-providers.js';
import { AuthenticationMethod } from '../../../../../src/identity-access-management/domain/models/AuthenticationMethod.js';
import { authenticateOidcUser } from '../../../../../src/identity-access-management/domain/usecases/authenticate-oidc-user.usecase.js';
import { RequestedApplication } from '../../../../../src/identity-access-management/infrastructure/utils/network.js';
import { ForbiddenAccess } from '../../../../../src/shared/domain/errors.js';
import { AdminMember } from '../../../../../src/shared/domain/models/AdminMember.js';
import { AuthenticationSessionContent } from '../../../../../src/shared/domain/models/AuthenticationSessionContent.js';
Expand All @@ -15,9 +16,11 @@ describe('Unit | Identity Access Management | Domain | UseCase | authenticate-oi
let userRepository;
let adminMemberRepository;
let userLoginRepository;
let lastUserApplicationConnectionsRepository;
let oidcAuthenticationServiceRegistry;
const externalIdentityId = '094b83ac-2e20-4aa8-b438-0bc91748e4a6';
const audience = 'https://app.pix.fr';
const requestedApplication = new RequestedApplication('app');

beforeEach(function () {
oidcAuthenticationService = {
Expand Down Expand Up @@ -47,6 +50,9 @@ describe('Unit | Identity Access Management | Domain | UseCase | authenticate-oi
userLoginRepository = {
updateLastLoggedAt: sinon.stub().resolves(),
};
lastUserApplicationConnectionsRepository = {
upsert: sinon.stub().resolves(),
};
});

context('check access by target', function () {
Expand Down Expand Up @@ -276,6 +282,8 @@ describe('Unit | Identity Access Management | Domain | UseCase | authenticate-oi
authenticationMethodRepository,
userRepository,
userLoginRepository,
lastUserApplicationConnectionsRepository,
requestedApplication,
});

// then
Expand Down Expand Up @@ -310,6 +318,8 @@ describe('Unit | Identity Access Management | Domain | UseCase | authenticate-oi
authenticationMethodRepository,
userRepository,
userLoginRepository,
requestedApplication,
lastUserApplicationConnectionsRepository,
});

// then
Expand All @@ -332,8 +342,10 @@ describe('Unit | Identity Access Management | Domain | UseCase | authenticate-oi
let userRepository;
let userLoginRepository;
let oidcAuthenticationServiceRegistry;
let lastUserApplicationConnectionsRepository;
const externalIdentityId = '094b83ac-2e20-4aa8-b438-0bc91748e4a6';
const audience = 'https://app.pix.fr';
const requestedApplication = new RequestedApplication('app');

beforeEach(function () {
oidcAuthenticationService = {
Expand Down Expand Up @@ -362,6 +374,9 @@ describe('Unit | Identity Access Management | Domain | UseCase | authenticate-oi
userLoginRepository = {
updateLastLoggedAt: sinon.stub().resolves(),
};
lastUserApplicationConnectionsRepository = {
upsert: sinon.stub().resolves(),
};
});

context('when user has an account', function () {
Expand All @@ -387,6 +402,8 @@ describe('Unit | Identity Access Management | Domain | UseCase | authenticate-oi
userRepository,
userLoginRepository,
audience,
requestedApplication,
lastUserApplicationConnectionsRepository,
});

// then
Expand Down Expand Up @@ -424,6 +441,8 @@ describe('Unit | Identity Access Management | Domain | UseCase | authenticate-oi
userRepository,
userLoginRepository,
audience,
requestedApplication,
lastUserApplicationConnectionsRepository,
});

// then
Expand Down Expand Up @@ -462,6 +481,8 @@ describe('Unit | Identity Access Management | Domain | UseCase | authenticate-oi
userRepository,
userLoginRepository,
audience,
requestedApplication,
lastUserApplicationConnectionsRepository,
});

// then
Expand Down

0 comments on commit 11b363c

Please sign in to comment.