From dc741b68c94f6456305d4c38e97cda33034ee749 Mon Sep 17 00:00:00 2001 From: Ismael Gorissen Date: Thu, 13 Jun 2024 18:38:51 +0200 Subject: [PATCH 1/3] feat(api): handle user language --- .../usecases/create-oidc-user.usecase.js | 23 +++++++++++-------- .../usecases/create-oidc-user.usecase.test.js | 9 +++++--- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/api/src/identity-access-management/domain/usecases/create-oidc-user.usecase.js b/api/src/identity-access-management/domain/usecases/create-oidc-user.usecase.js index e983c52c506..e1be78dedff 100644 --- a/api/src/identity-access-management/domain/usecases/create-oidc-user.usecase.js +++ b/api/src/identity-access-management/domain/usecases/create-oidc-user.usecase.js @@ -3,22 +3,24 @@ import { AuthenticationKeyExpired } from '../errors.js'; import { UserToCreate } from '../models/UserToCreate.js'; /** - * @typedef {function} createOidcUser - * @param {Object} params - * @param {string} params.identityProvider - * @param {string} params.authenticationKey - * @param {string} params.localeFromCookie - * @param {AuthenticationSessionService} params.authenticationSessionService - * @param {OidcAuthenticationServiceRegistry} params.oidcAuthenticationServiceRegistry - * @param {AuthenticationMethodRepository} params.authenticationMethodRepository - * @param {UserToCreateRepository} params.userToCreateRepository - * @param {UserLoginRepository} params.userLoginRepository + * @param {{ + * identityProvider: string, + * authenticationKey: string, + * localeFromCookie: string, + * language: string, + * authenticationSessionService: AuthenticationSessionService, + * oidcAuthenticationServiceRegistry: OidcAuthenticationServiceRegistry, + * authenticationMethodRepository: AuthenticationMethodRepository, + * userToCreateRepository: UserToCreateRepository, + * userLoginRepository: UserLoginRepository, + * }} params * @return {Promise<{accessToken: string, logoutUrlUUID: string}>} */ async function createOidcUser({ identityProvider, authenticationKey, localeFromCookie, + language, authenticationSessionService, oidcAuthenticationServiceRegistry, authenticationMethodRepository, @@ -47,6 +49,7 @@ async function createOidcUser({ firstName: userInfo.firstName, lastName: userInfo.lastName, locale: localeFromCookie, + lang: language, }); await oidcAuthenticationServiceRegistry.loadOidcProviderServices(); diff --git a/api/tests/identity-access-management/unit/domain/usecases/create-oidc-user.usecase.test.js b/api/tests/identity-access-management/unit/domain/usecases/create-oidc-user.usecase.test.js index a2977b20ffc..934035080cb 100644 --- a/api/tests/identity-access-management/unit/domain/usecases/create-oidc-user.usecase.test.js +++ b/api/tests/identity-access-management/unit/domain/usecases/create-oidc-user.usecase.test.js @@ -89,9 +89,10 @@ describe('Unit | Identity Access Management | Domain | UseCase | create-oidc-use }); }); - it('creates the user account and returns an access token, the logout url uuid and update the last logged date with the existing external user id', async function () { + it('creates the user account with given language and returns an access token, the logout url uuid and update the last logged date with the existing external user id', async function () { // given const idToken = 'idToken'; + const language = 'nl'; authenticationSessionService.getByKey.withArgs('AUTHENTICATION_KEY').resolves({ sessionContent: { idToken, accessToken: 'accessToken' }, userInfo: { firstName: 'Jean', lastName: 'Heymar', externalIdentityId: 'externalId' }, @@ -107,7 +108,8 @@ describe('Unit | Identity Access Management | Domain | UseCase | create-oidc-use const result = await createOidcUser({ identityProvider: 'SOME_IDP', authenticationKey: 'AUTHENTICATION_KEY', - localeFromCookie: 'fr-FR', + localeFromCookie: 'nl-BE', + language, authenticationSessionService, oidcAuthenticationServiceRegistry, authenticationMethodRepository, @@ -120,7 +122,8 @@ describe('Unit | Identity Access Management | Domain | UseCase | create-oidc-use user: { firstName: 'Jean', lastName: 'Heymar', - locale: 'fr-FR', + locale: 'nl-BE', + lang: 'nl', cgu: true, lastTermsOfServiceValidatedAt: now, }, From cbca40d14d8f34c060d1f23973d3941ca30b436a Mon Sep 17 00:00:00 2001 From: Ismael Gorissen Date: Thu, 13 Jun 2024 18:54:03 +0200 Subject: [PATCH 2/3] feat(api): retrieve language from request headers --- .../application/oidc-provider/oidc-provider.controller.js | 7 ++++++- .../acceptance/application/oidc-provider.route.test.js | 1 + .../unit/application/oidc-provider.controller.test.js | 4 ++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/api/src/identity-access-management/application/oidc-provider/oidc-provider.controller.js b/api/src/identity-access-management/application/oidc-provider/oidc-provider.controller.js index 5d388f49474..d86c34ed3fa 100644 --- a/api/src/identity-access-management/application/oidc-provider/oidc-provider.controller.js +++ b/api/src/identity-access-management/application/oidc-provider/oidc-provider.controller.js @@ -2,6 +2,9 @@ import { BadRequestError, UnauthorizedError } from '../../../../lib/application/ import * as oidcSerializer from '../../../../lib/infrastructure/serializers/jsonapi/oidc-serializer.js'; import { usecases } from '../../domain/usecases/index.js'; import * as oidcProviderSerializer from '../../infrastructure/serializers/jsonapi/oidc-identity-providers.serializer.js'; +import { + requestResponseUtils, +} from '../../../shared/infrastructure/utils/request-response-utils.js'; /** * @typedef {function} authenticateOidcUser @@ -52,14 +55,16 @@ async function authenticateOidcUser(request, h) { * @param h * @return {Promise<{access_token: string, logout_url_uuid: string}>} */ -async function createUser(request, h) { +async function createUser(request, h, dependencies = { requestResponseUtils }) { const { identityProvider, authenticationKey } = request.deserializedPayload; const localeFromCookie = request.state?.locale; + const language = dependencies.requestResponseUtils.extractLocaleFromRequest(request); const { accessToken: access_token, logoutUrlUUID: logout_url_uuid } = await usecases.createOidcUser({ authenticationKey, identityProvider, localeFromCookie, + language, }); return h.response({ access_token, logout_url_uuid }).code(200); diff --git a/api/tests/identity-access-management/acceptance/application/oidc-provider.route.test.js b/api/tests/identity-access-management/acceptance/application/oidc-provider.route.test.js index 148db8c8044..5b422350965 100644 --- a/api/tests/identity-access-management/acceptance/application/oidc-provider.route.test.js +++ b/api/tests/identity-access-management/acceptance/application/oidc-provider.route.test.js @@ -446,6 +446,7 @@ describe('Acceptance | Identity Access Management | Application | Route | oidc-p method: 'POST', url: '/api/oidc/users', headers: { + 'accept-language': 'fr', cookie: 'locale=fr-FR', }, payload: { diff --git a/api/tests/identity-access-management/unit/application/oidc-provider.controller.test.js b/api/tests/identity-access-management/unit/application/oidc-provider.controller.test.js index f04cc211214..091afe96a80 100644 --- a/api/tests/identity-access-management/unit/application/oidc-provider.controller.test.js +++ b/api/tests/identity-access-management/unit/application/oidc-provider.controller.test.js @@ -115,6 +115,9 @@ describe('Unit | Identity Access Management | Application | Controller | oidc-pr // given const request = { deserializedPayload: { identityProvider: 'OIDC', authenticationKey: 'abcde' }, + headers: { + 'accept-language': 'fr', + }, state: { locale: 'fr-FR', }, @@ -132,6 +135,7 @@ describe('Unit | Identity Access Management | Application | Controller | oidc-pr identityProvider: 'OIDC', authenticationKey: 'abcde', localeFromCookie: 'fr-FR', + language: 'fr', }); expect(response.statusCode).to.equal(200); expect(response.source).to.deep.equal({ From 14b3b7b139a6d7f4ef86feb039d0fcee2d8b5cb9 Mon Sep 17 00:00:00 2001 From: Ismael Gorissen Date: Thu, 13 Jun 2024 19:14:08 +0200 Subject: [PATCH 3/3] feat(mon-pix): add application language to request --- .../application/oidc-provider/oidc-provider.controller.js | 4 +--- mon-pix/app/authenticators/oidc.js | 4 +++- mon-pix/tests/unit/authenticators/oidc_test.js | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/api/src/identity-access-management/application/oidc-provider/oidc-provider.controller.js b/api/src/identity-access-management/application/oidc-provider/oidc-provider.controller.js index d86c34ed3fa..bc127b875a3 100644 --- a/api/src/identity-access-management/application/oidc-provider/oidc-provider.controller.js +++ b/api/src/identity-access-management/application/oidc-provider/oidc-provider.controller.js @@ -1,10 +1,8 @@ import { BadRequestError, UnauthorizedError } from '../../../../lib/application/http-errors.js'; import * as oidcSerializer from '../../../../lib/infrastructure/serializers/jsonapi/oidc-serializer.js'; +import { requestResponseUtils } from '../../../shared/infrastructure/utils/request-response-utils.js'; import { usecases } from '../../domain/usecases/index.js'; import * as oidcProviderSerializer from '../../infrastructure/serializers/jsonapi/oidc-identity-providers.serializer.js'; -import { - requestResponseUtils, -} from '../../../shared/infrastructure/utils/request-response-utils.js'; /** * @typedef {function} authenticateOidcUser diff --git a/mon-pix/app/authenticators/oidc.js b/mon-pix/app/authenticators/oidc.js index f5443cafee0..56301fd1f84 100644 --- a/mon-pix/app/authenticators/oidc.js +++ b/mon-pix/app/authenticators/oidc.js @@ -7,15 +7,17 @@ import { decodeToken } from 'mon-pix/helpers/jwt'; import RSVP from 'rsvp'; export default class OidcAuthenticator extends BaseAuthenticator { - @service session; + @service intl; @service location; @service oidcIdentityProviders; + @service session; async authenticate({ code, state, identityProviderSlug, authenticationKey, hostSlug }) { const request = { method: 'POST', headers: { Accept: 'application/json', + 'Accept-Language': this.intl.primaryLocale, 'Content-Type': 'application/json', }, }; diff --git a/mon-pix/tests/unit/authenticators/oidc_test.js b/mon-pix/tests/unit/authenticators/oidc_test.js index edbf23179b0..7669c243d8e 100644 --- a/mon-pix/tests/unit/authenticators/oidc_test.js +++ b/mon-pix/tests/unit/authenticators/oidc_test.js @@ -4,8 +4,11 @@ import * as fetch from 'fetch'; import { module, test } from 'qunit'; import sinon from 'sinon'; +import setupIntl from '../../helpers/setup-intl'; + module('Unit | Authenticator | oidc', function (hooks) { setupTest(hooks); + setupIntl(hooks); module('#authenticate', function (hooks) { const userId = 1; @@ -78,6 +81,7 @@ module('Unit | Authenticator | oidc', function (hooks) { }); // then + request.headers['Accept-Language'] = 'fr'; request.body = JSON.stringify({ data: { attributes: {