diff --git a/app/frontend/src/components/base/BaseSecure.vue b/app/frontend/src/components/base/BaseSecure.vue index 30da86712..f4ee5e424 100755 --- a/app/frontend/src/components/base/BaseSecure.vue +++ b/app/frontend/src/components/base/BaseSecure.vue @@ -10,10 +10,6 @@ export default { type: Boolean, default: false, }, - idp: { - type: Array, - default: undefined, - }, permission: { type: String, default: undefined, diff --git a/app/frontend/src/internationalization/trans/chefs/ar/ar.json b/app/frontend/src/internationalization/trans/chefs/ar/ar.json index d216913f6..3bd8bb3f6 100644 --- a/app/frontend/src/internationalization/trans/chefs/ar/ar.json +++ b/app/frontend/src/internationalization/trans/chefs/ar/ar.json @@ -377,7 +377,7 @@ "401NotAuthorized": "401: غير مصرح به. :", "401ErrorMsg": "لم يتم إعداد حسابك بشكل صحيح.
الرجاء التواصل", "403Forbidden": "403 ممنوع. :", - "403ErrorMsg": "تتطلب هذه الصفحة مصادقة {idp}.", + "403ErrorMsg": "تتطلب هذه الصفحة مصادقة {permission}.", "401UnAuthorized": "401: غير مصرح به. :", "401UnAuthorizedErrMsg": "ليس لديك الصلاحية لدخول هذه الصفحة." }, diff --git a/app/frontend/src/internationalization/trans/chefs/de/de.json b/app/frontend/src/internationalization/trans/chefs/de/de.json index 8561f37eb..331949d4f 100644 --- a/app/frontend/src/internationalization/trans/chefs/de/de.json +++ b/app/frontend/src/internationalization/trans/chefs/de/de.json @@ -377,7 +377,7 @@ "401NotAuthorized": "401: nicht autorisiert. :", "401ErrorMsg": "Ihr Konto ist nicht richtig eingerichtet.
Kontaktieren Sie bitte", "403Forbidden": "403 Verboten. :", - "403ErrorMsg": "Diese Seite erfordert eine {idp}-Authentifizierung.", + "403ErrorMsg": "Diese Seite erfordert eine {permission}-Authentifizierung.", "401UnAuthorized": "401 nicht Autorisiert. :", "401UnAuthorizedErrMsg": "Sie haben keine Berechtigung, auf diese Seite zuzugreifen." }, diff --git a/app/frontend/src/internationalization/trans/chefs/en/en.json b/app/frontend/src/internationalization/trans/chefs/en/en.json index 288b06d88..577e92fe8 100644 --- a/app/frontend/src/internationalization/trans/chefs/en/en.json +++ b/app/frontend/src/internationalization/trans/chefs/en/en.json @@ -373,7 +373,7 @@ "401NotAuthorized": "401: not authorized. :(", "401ErrorMsg": "Your account is not set up correctly.
Please contact", "403Forbidden": "403: Forbidden. :(", - "403ErrorMsg": "This page requires {idp} authentication.", + "403ErrorMsg": "This page requires {permission} permission.", "401UnAuthorized": "401: Unauthorized. :(", "401UnAuthorizedErrMsg": "You do not have permission to access this page." }, diff --git a/app/frontend/src/internationalization/trans/chefs/es/es.json b/app/frontend/src/internationalization/trans/chefs/es/es.json index 4f2b44a9e..372873551 100644 --- a/app/frontend/src/internationalization/trans/chefs/es/es.json +++ b/app/frontend/src/internationalization/trans/chefs/es/es.json @@ -377,7 +377,7 @@ "401NotAuthorized": "401: no autorizado. :", "401ErrorMsg": "Su cuenta no está configurada correctamente.
Por favor contactar", "403Forbidden": "403: Prohibido. :", - "403ErrorMsg": "Esta página requiere autenticación {idp}.", + "403ErrorMsg": "Esta página requiere autenticación {permission}.", "401UnAuthorized": "401: No autorizado. :", "401UnAuthorizedErrMsg": "Usted no tiene permiso para acceder a esta página." }, diff --git a/app/frontend/src/internationalization/trans/chefs/fa/fa.json b/app/frontend/src/internationalization/trans/chefs/fa/fa.json index 4e55afbc6..f899dbf92 100644 --- a/app/frontend/src/internationalization/trans/chefs/fa/fa.json +++ b/app/frontend/src/internationalization/trans/chefs/fa/fa.json @@ -377,7 +377,7 @@ "401NotAuthorized": "401: مجاز نیست. :", "401ErrorMsg": "حساب شما به درستی تنظیم نشده است.
لطفا تماس بگیرید", "403Forbidden": "403: ممنوع. :", - "403ErrorMsg": "این صفحه به احراز هویت {idp} نیاز دارد.", + "403ErrorMsg": "این صفحه به احراز هویت {permission} نیاز دارد.", "401UnAuthorized": "401: غیر مجاز. :", "401UnAuthorizedErrMsg": "شما اجازه دسترسی به این صفحه را ندارید." }, diff --git a/app/frontend/src/internationalization/trans/chefs/fr/fr.json b/app/frontend/src/internationalization/trans/chefs/fr/fr.json index 2f7290588..b0013d276 100644 --- a/app/frontend/src/internationalization/trans/chefs/fr/fr.json +++ b/app/frontend/src/internationalization/trans/chefs/fr/fr.json @@ -377,7 +377,7 @@ "401NotAuthorized": "401 : non autorisé. :", "401ErrorMsg": "Votre compte n'est pas configuré correctement.
S'il vous plaît contactez", "403Forbidden": "403 : Interdit. :", - "403ErrorMsg": "Cette page nécessite une authentification {idp}.", + "403ErrorMsg": "Cette page nécessite une authentification {permission}.", "401UnAuthorized": "401 : non autorisé. :", "401UnAuthorizedErrMsg": "Vous n'avez pas la permission d'accéder à cette page." }, diff --git a/app/frontend/src/internationalization/trans/chefs/hi/hi.json b/app/frontend/src/internationalization/trans/chefs/hi/hi.json index 55858556f..d3333ac31 100644 --- a/app/frontend/src/internationalization/trans/chefs/hi/hi.json +++ b/app/frontend/src/internationalization/trans/chefs/hi/hi.json @@ -377,7 +377,7 @@ "401NotAuthorized": "401: अधिकृत नहीं. :", "401ErrorMsg": "आपका खाता ठीक से सेट नहीं है.
कृपया संपर्क करें", "403Forbidden": "403 निषिद्ध। :", - "403ErrorMsg": "इस पृष्ठ को {idp} प्रमाणीकरण की आवश्यकता है।", + "403ErrorMsg": "इस पृष्ठ को {permission} प्रमाणीकरण की आवश्यकता है।", "401UnAuthorized": "अनधिकृत 401। :", "401UnAuthorizedErrMsg": "आपको इस पेज को एक्सेस करने की अनुमति नहीं है।" }, diff --git a/app/frontend/src/internationalization/trans/chefs/it/it.json b/app/frontend/src/internationalization/trans/chefs/it/it.json index 7f700a239..c0556044d 100644 --- a/app/frontend/src/internationalization/trans/chefs/it/it.json +++ b/app/frontend/src/internationalization/trans/chefs/it/it.json @@ -377,7 +377,7 @@ "401NotAuthorized": "401: non autorizzato. :", "401ErrorMsg": "Il tuo account non è impostato correttamente.
Si prega di contattare", "403Forbidden": "403: Proibito. :", - "403ErrorMsg": "Questa pagina richiede l'autenticazione {idp}.", + "403ErrorMsg": "Questa pagina richiede l'autenticazione {permission}.", "401UnAuthorized": "401: non autorizzato. :", "401UnAuthorizedErrMsg": "Non sei autorizzato ad accedere a questa pagina." }, diff --git a/app/frontend/src/internationalization/trans/chefs/ja/ja.json b/app/frontend/src/internationalization/trans/chefs/ja/ja.json index 2e3031d75..1f7ed1f81 100644 --- a/app/frontend/src/internationalization/trans/chefs/ja/ja.json +++ b/app/frontend/src/internationalization/trans/chefs/ja/ja.json @@ -377,7 +377,7 @@ "401NotAuthorized": "401: 権限がありません。 :", "401ErrorMsg": "アカウントが正しく設定されていません。
お問い合わせください", "403Forbidden": "403禁止します。 :", - "403ErrorMsg": "このページには {idp} 認証が必要です。", + "403ErrorMsg": "このページには {permission} 認証が必要です。", "401UnAuthorized": "401: 不正です。 :", "401UnAuthorizedErrMsg": "このページにアクセスする権限がありません。" }, diff --git a/app/frontend/src/internationalization/trans/chefs/ko/ko.json b/app/frontend/src/internationalization/trans/chefs/ko/ko.json index c95a5b9d9..6e7b08627 100644 --- a/app/frontend/src/internationalization/trans/chefs/ko/ko.json +++ b/app/frontend/src/internationalization/trans/chefs/ko/ko.json @@ -377,7 +377,7 @@ "401NotAuthorized": "401: 권한이 없습니다. :", "401ErrorMsg": "귀하의 계정이 올바르게 설정되지 않았습니다.
연락주세요", "403Forbidden": "403 금지. :", - "403ErrorMsg": "이 페이지는 {idp} 인증이 필요합니다.", + "403ErrorMsg": "이 페이지는 {permission} 인증이 필요합니다.", "401UnAuthorized": "401: 권한이 없습니다. :", "401UnAuthorizedErrMsg": "이 페이지에 액세스할 수 있는 권한이 없습니다." }, diff --git a/app/frontend/src/internationalization/trans/chefs/pa/pa.json b/app/frontend/src/internationalization/trans/chefs/pa/pa.json index 5ec033ee3..f05c92ef0 100644 --- a/app/frontend/src/internationalization/trans/chefs/pa/pa.json +++ b/app/frontend/src/internationalization/trans/chefs/pa/pa.json @@ -377,7 +377,7 @@ "401NotAuthorized": "401: ਅਧਿਕਾਰਤ ਨਹੀਂ। :", "401ErrorMsg": "ਤੁਹਾਡਾ ਖਾਤਾ ਸਹੀ ਢੰਗ ਨਾਲ ਸੈੱਟਅੱਪ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ।
ਕਿਰਪਾ ਕਰਕੇ ਸੰਪਰਕ ਕਰੋ", "403Forbidden": "403: ਵਰਜਿਤ। :", - "403ErrorMsg": "ਇਸ ਪੰਨੇ ਨੂੰ {idp} ਪ੍ਰਮਾਣੀਕਰਨ ਦੀ ਲੋੜ ਹੈ।", + "403ErrorMsg": "ਇਸ ਪੰਨੇ ਨੂੰ {permission} ਪ੍ਰਮਾਣੀਕਰਨ ਦੀ ਲੋੜ ਹੈ।", "401UnAuthorized": "401: ਅਣਅਧਿਕਾਰਤ। :", "401UnAuthorizedErrMsg": "ਤੁਹਾਨੂੰ ਇਸ ਪੰਨੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ।" }, diff --git a/app/frontend/src/internationalization/trans/chefs/pt/pt.json b/app/frontend/src/internationalization/trans/chefs/pt/pt.json index 983c5fdb6..6d30dd28d 100644 --- a/app/frontend/src/internationalization/trans/chefs/pt/pt.json +++ b/app/frontend/src/internationalization/trans/chefs/pt/pt.json @@ -377,7 +377,7 @@ "401NotAuthorized": "401: não autorizado. :", "401ErrorMsg": "Sua conta não está configurada corretamente.
Por favor entre em contato", "403Forbidden": "403: Proibido. :", - "403ErrorMsg": "Esta página requer autenticação {idp}.", + "403ErrorMsg": "Esta página requer autenticação {permission}.", "401UnAuthorized": "401 não autorizado. :", "401UnAuthorizedErrMsg": "Você não tem permissão para acessar esta página." }, diff --git a/app/frontend/src/internationalization/trans/chefs/ru/ru.json b/app/frontend/src/internationalization/trans/chefs/ru/ru.json index acae1fd01..5ab21646e 100644 --- a/app/frontend/src/internationalization/trans/chefs/ru/ru.json +++ b/app/frontend/src/internationalization/trans/chefs/ru/ru.json @@ -377,7 +377,7 @@ "401NotAuthorized": "401: не авторизован:", "401ErrorMsg": "Ваша учетная запись настроена неправильно.
Пожалуйста свяжитесь с нами", "403Forbidden": "403: Запрещено:", - "403ErrorMsg": "Для этой страницы требуется аутентификация {idp}.", + "403ErrorMsg": "Для этой страницы требуется аутентификация {permission}.", "401UnAuthorized": "401: Неавторизованный. :", "401UnAuthorizedErrMsg": "Вы не имеете доступа к этой странице." }, diff --git a/app/frontend/src/internationalization/trans/chefs/tl/tl.json b/app/frontend/src/internationalization/trans/chefs/tl/tl.json index 9ab1f3313..647ca319d 100644 --- a/app/frontend/src/internationalization/trans/chefs/tl/tl.json +++ b/app/frontend/src/internationalization/trans/chefs/tl/tl.json @@ -377,7 +377,7 @@ "401NotAuthorized": "401: hindi awtorisado. :", "401ErrorMsg": "Ang iyong account ay hindi na-set up nang tama.
Mangyaring makipag-ugnayan", "403Forbidden": "403 Ipinagbabawal. :", - "403ErrorMsg": "Nangangailangan ang page na ito ng {idp} authentication.", + "403ErrorMsg": "Nangangailangan ang page na ito ng {permission} authentication.", "401UnAuthorized": "401: Hindi awtorisado. :", "401UnAuthorizedErrMsg": "Wala kang pahintulot na i-access ang pahinang ito." }, diff --git a/app/frontend/src/internationalization/trans/chefs/uk/uk.json b/app/frontend/src/internationalization/trans/chefs/uk/uk.json index 41f5122c0..695452f64 100644 --- a/app/frontend/src/internationalization/trans/chefs/uk/uk.json +++ b/app/frontend/src/internationalization/trans/chefs/uk/uk.json @@ -377,7 +377,7 @@ "401NotAuthorized": "401: не авторизовано. :", "401ErrorMsg": "Ваш обліковий запис налаштовано неправильно.
Будь ласка зв'яжіться", "403Forbidden": "403 Заборонено. :", - "403ErrorMsg": "Для цієї сторінки потрібна автентифікація {idp}.", + "403ErrorMsg": "Для цієї сторінки потрібна автентифікація {permission}.", "401UnAuthorized": "401: неавторизовано. :", "401UnAuthorizedErrMsg": "Ви не маєте дозволу на доступ до цієї сторінки." }, diff --git a/app/frontend/src/internationalization/trans/chefs/vi/vi.json b/app/frontend/src/internationalization/trans/chefs/vi/vi.json index 7f440b7d9..73872a2e7 100644 --- a/app/frontend/src/internationalization/trans/chefs/vi/vi.json +++ b/app/frontend/src/internationalization/trans/chefs/vi/vi.json @@ -377,7 +377,7 @@ "401NotAuthorized": "401: không được ủy quyền. :", "401ErrorMsg": "Tài khoản của bạn không được thiết lập chính xác.
Vui lòng liên hệ", "403Forbidden": "403: Cấm. :", - "403ErrorMsg": "Trang này yêu cầu xác thực {idp}.", + "403ErrorMsg": "Trang này yêu cầu xác thực {permission}.", "401UnAuthorized": "401: Trái phép. :", "401UnAuthorizedErrMsg": "Bạn không có quyền truy cập trang này." }, diff --git a/app/frontend/src/internationalization/trans/chefs/zh/zh.json b/app/frontend/src/internationalization/trans/chefs/zh/zh.json index 4bdb517a1..74aaa5222 100644 --- a/app/frontend/src/internationalization/trans/chefs/zh/zh.json +++ b/app/frontend/src/internationalization/trans/chefs/zh/zh.json @@ -377,7 +377,7 @@ "401NotAuthorized": "401:未授权。 :", "401ErrorMsg": "您的帐户设置不正确。
请联系", "403Forbidden": "403:禁止。 :", - "403ErrorMsg": "此页面需要 {idp} 身份验证。", + "403ErrorMsg": "此页面需要 {permission} 身份验证。", "401UnAuthorized": "401:未经授权。 :", "401UnAuthorizedErrMsg": "您没有权限访问此页面。" }, diff --git a/app/frontend/src/internationalization/trans/chefs/zhTW/zh-TW.json b/app/frontend/src/internationalization/trans/chefs/zhTW/zh-TW.json index 2a01e8e1d..88d856e10 100644 --- a/app/frontend/src/internationalization/trans/chefs/zhTW/zh-TW.json +++ b/app/frontend/src/internationalization/trans/chefs/zhTW/zh-TW.json @@ -377,7 +377,7 @@ "401NotAuthorized": "401:未授權。 :", "401ErrorMsg": "您的帳戶設置不正確。
請聯繫", "403Forbidden": "403:禁止。 :", - "403ErrorMsg": "此頁面需要 {idp} 身份驗證。", + "403ErrorMsg": "此頁面需要 {permission} 身份驗證。", "401UnAuthorized": "401:未經授權。 :", "401UnAuthorizedErrMsg": "您沒有權限訪問此頁面。" }, diff --git a/app/frontend/tests/unit/components/base/BaseAuthButton.spec.js b/app/frontend/tests/unit/components/base/BaseAuthButton.spec.js index ed57037c8..d7f7b60ca 100644 --- a/app/frontend/tests/unit/components/base/BaseAuthButton.spec.js +++ b/app/frontend/tests/unit/components/base/BaseAuthButton.spec.js @@ -8,13 +8,16 @@ import { vi } from 'vitest'; import getRouter from '~/router'; import BaseAuthButton from '~/components/base/BaseAuthButton.vue'; import { useAuthStore } from '~/store/auth'; +import { useIdpStore } from '~/store/identityProviders'; describe('BaseAuthButton.vue', () => { const pinia = createPinia(); setActivePinia(pinia); const authStore = useAuthStore(); + const idpStore = useIdpStore(); const router = getRouter(); const windowReplaceSpy = vi.spyOn(window.location, 'replace'); + idpStore.providers = require('../../fixtures/identityProviders.json'); beforeEach(async () => { windowReplaceSpy.mockReset(); @@ -95,7 +98,7 @@ describe('BaseAuthButton.vue', () => { expect(replace).toHaveBeenCalledTimes(1); expect(replace).toHaveBeenCalledWith({ name: 'Login', - query: { idpHint: ['idir', 'bceid-business', 'bceid-basic'] }, + query: { idpHint: idpStore.loginIdpHints }, }); }); diff --git a/app/frontend/tests/unit/components/base/BaseSecure.spec.js b/app/frontend/tests/unit/components/base/BaseSecure.spec.js index c2ea0e590..d60435ac9 100644 --- a/app/frontend/tests/unit/components/base/BaseSecure.spec.js +++ b/app/frontend/tests/unit/components/base/BaseSecure.spec.js @@ -9,6 +9,8 @@ import { expect, vi } from 'vitest'; import getRouter from '~/router'; import BaseSecure from '~/components/base/BaseSecure.vue'; import { useAuthStore } from '~/store/auth'; +import { useIdpStore } from '~/store/identityProviders'; +import { AppPermissions } from '~/utils/constants'; describe('BaseSecure.vue', () => { const pinia = createPinia(); @@ -19,6 +21,12 @@ describe('BaseSecure.vue', () => { setActivePinia(pinia); const authStore = useAuthStore(); + const idpStore = useIdpStore(); + + idpStore.providers = require('../../fixtures/identityProviders.json'); + const nonPrimaryIdp = idpStore.providers.find( + (x) => x.active && x.login && !x.primary + ); it('renders nothing if authenticated, user', () => { authStore.authenticated = true; @@ -30,6 +38,7 @@ describe('BaseSecure.vue', () => { roles: ['user'], }, }, + identity_provider: nonPrimaryIdp.code, }, }; const wrapper = mount(BaseSecure, { @@ -51,6 +60,7 @@ describe('BaseSecure.vue', () => { roles: [], }, }, + identity_provider: nonPrimaryIdp.code, }, }; const wrapper = mount(BaseSecure, { @@ -71,6 +81,7 @@ describe('BaseSecure.vue', () => { chefs: { roles: ['user'], }, + identity_provider: nonPrimaryIdp.code, }, }, }; @@ -96,6 +107,7 @@ describe('BaseSecure.vue', () => { roles: ['user'], }, }, + identity_provider: nonPrimaryIdp.code, }, }; const wrapper = mount(BaseSecure, { @@ -170,13 +182,14 @@ describe('BaseSecure.vue', () => { chefs: { roles: ['user'], }, + identity_provider: nonPrimaryIdp.code, }, }, }; const wrapper = mount(BaseSecure, { props: { admin: false, - idp: ['IDIR'], + permission: AppPermissions.VIEWS_ADMIN, }, global: { plugins: [router, pinia], diff --git a/app/frontend/tests/unit/components/bcgov/BCGovNavBar.spec.js b/app/frontend/tests/unit/components/bcgov/BCGovNavBar.spec.js index 751a0500a..2e0b3b502 100644 --- a/app/frontend/tests/unit/components/bcgov/BCGovNavBar.spec.js +++ b/app/frontend/tests/unit/components/bcgov/BCGovNavBar.spec.js @@ -9,6 +9,7 @@ import { VApp } from 'vuetify/components'; import BCGovNavBar from '~/components/bcgov/BCGovNavBar.vue'; import getRouter from '~/router'; import { useAuthStore } from '~/store/auth'; +import { useIdpStore } from '~/store/identityProviders'; describe('BCGovNavBar.vue', () => { const pinia = createPinia(); @@ -17,12 +18,16 @@ describe('BCGovNavBar.vue', () => { history: createWebHistory(), routes: getRouter().getRoutes(), }); + const idpStore = useIdpStore(); + + idpStore.providers = require('../../fixtures/identityProviders'); + const primaryIdp = idpStore.primaryIdp; it('renders as non-admin', async () => { const authStore = useAuthStore(); authStore.keycloak = { tokenParsed: { - identity_provider: 'idir', + identity_provider: primaryIdp.code, resource_access: { chefs: { roles: [], @@ -64,7 +69,7 @@ describe('BCGovNavBar.vue', () => { const authStore = useAuthStore(); authStore.keycloak = { tokenParsed: { - identity_provider: 'idir', + identity_provider: primaryIdp.code, resource_access: { chefs: { roles: ['admin'], diff --git a/app/frontend/tests/unit/fixtures/identityProviders.json b/app/frontend/tests/unit/fixtures/identityProviders.json new file mode 100644 index 000000000..3b757c0d7 --- /dev/null +++ b/app/frontend/tests/unit/fixtures/identityProviders.json @@ -0,0 +1,119 @@ +[ + { + "code": "idir", + "display": "IDIR", + "active": true, + "idp": "idir", + "createdBy": "migration-002", + "createdAt": "2024-01-24T22:35:49.703Z", + "updatedBy": null, + "updatedAt": "2024-01-24T22:35:49.703Z", + "primary": true, + "login": true, + "permissions": [ + "views_form_stepper", + "views_admin", + "views_file_download", + "views_form_emails", + "views_form_export", + "views_form_manage", + "views_form_preview", + "views_form_submissions", + "views_form_teamS", + "views_form_view", + "views_user_submissions" + ], + "roles": [ + "owner", + "team_manager", + "form_designer", + "submission_reviewer", + "form_submitter" + ], + "extra": {} + }, + { + "code": "bceid-basic", + "display": "Basic BCeID", + "active": true, + "idp": "bceid-basic", + "createdBy": "migration-022", + "createdAt": "2024-01-24T22:35:49.703Z", + "updatedBy": null, + "updatedAt": "2024-01-24T22:35:49.703Z", + "primary": false, + "login": true, + "permissions": [ + "views_user_submissions" + ], + "roles": [ + "form_submitter" + ], + "extra": { + "formAccessSettings": "idim", + "addTeamMemberSearch": { + "text": { + "message": "trans.manageSubmissionUsers.searchInputLength", + "minLength": 6 + }, + "email": { + "exact": true, + "message": "trans.manageSubmissionUsers.exactBCEIDSearch" + } + } + } + }, + { + "code": "bceid-business", + "display": "Business BCeID", + "active": true, + "idp": "bceid-business", + "createdBy": "migration-022", + "createdAt": "2024-01-24T22:35:49.703Z", + "updatedBy": null, + "updatedAt": "2024-01-24T22:35:49.703Z", + "primary": false, + "login": true, + "permissions": [ + "views_form_export", + "views_form_manage", + "views_form_submissions", + "views_form_teamS", + "views_form_view", + "views_user_submissions" + ], + "roles": [ + "team_manager", + "submission_reviewer", + "form_submitter" + ], + "extra": { + "formAccessSettings": "idim", + "addTeamMemberSearch": { + "text": { + "message": "trans.manageSubmissionUsers.searchInputLength", + "minLength": 6 + }, + "email": { + "exact": true, + "message": "trans.manageSubmissionUsers.exactBCEIDSearch" + } + } + } + }, + { + "code": "public", + "display": "Public", + "active": true, + "idp": "public", + "createdBy": "migration-002", + "createdAt": "2024-01-24T22:35:49.703Z", + "updatedBy": null, + "updatedAt": "2024-01-24T22:35:49.703Z", + "primary": false, + "login": false, + "permissions": [], + "roles": null, + "extra": {} + } +] \ No newline at end of file diff --git a/app/frontend/tests/unit/store/modules/auth.actions.spec.js b/app/frontend/tests/unit/store/modules/auth.actions.spec.js index 920aac5f9..1e482b7e4 100644 --- a/app/frontend/tests/unit/store/modules/auth.actions.spec.js +++ b/app/frontend/tests/unit/store/modules/auth.actions.spec.js @@ -6,6 +6,7 @@ import getRouter from '~/router'; import { useAuthStore } from '~/store/auth'; import { useFormStore } from '~/store/form'; +import { useIdpStore } from '~/store/identityProviders'; describe('auth actions', () => { let router = getRouter(); @@ -14,6 +15,9 @@ describe('auth actions', () => { setActivePinia(createPinia()); const mockStore = useAuthStore(); const formStore = useFormStore(); + const idpStore = useIdpStore(); + + idpStore.providers = require('../../fixtures/identityProviders.json'); describe('login', () => { beforeEach(() => { @@ -74,7 +78,7 @@ describe('auth actions', () => { expect(replaceSpy).toHaveBeenCalledTimes(1); expect(replaceSpy).toHaveBeenCalledWith({ name: 'Login', - query: { idpHint: ['idir', 'bceid-business', 'bceid-basic'] }, + query: { idpHint: idpStore.loginIdpHints }, }); }); diff --git a/app/frontend/tests/unit/utils/constants.spec.js b/app/frontend/tests/unit/utils/constants.spec.js index 512b9a2c4..7540826cf 100644 --- a/app/frontend/tests/unit/utils/constants.spec.js +++ b/app/frontend/tests/unit/utils/constants.spec.js @@ -68,11 +68,19 @@ describe('Constants', () => { }); }); - it('IdentityProviders has the right values defined', () => { - expect(constants.IdentityProviders).toEqual({ - BCEIDBASIC: 'bceid-basic', - BCEIDBUSINESS: 'bceid-business', - IDIR: 'idir', + it('AppPermissions has the right values defined', () => { + expect(constants.AppPermissions).toEqual({ + VIEWS_FORM_STEPPER: 'views_form_stepper', + VIEWS_ADMIN: 'views_admin', + VIEWS_FILE_DOWNLOAD: 'views_file_download', + VIEWS_FORM_EMAILS: 'views_form_emails', + VIEWS_FORM_EXPORT: 'views_form_export', + VIEWS_FORM_MANAGE: 'views_form_manage', + VIEWS_FORM_PREVIEW: 'views_form_preview', + VIEWS_FORM_SUBMISSIONS: 'views_form_submissions', + VIEWS_FORM_TEAMS: 'views_form_teamS', + VIEWS_FORM_VIEW: 'views_form_view', + VIEWS_USER_SUBMISSIONS: 'views_user_submissions', }); }); diff --git a/app/frontend/tests/unit/utils/permissionUtils.spec.js b/app/frontend/tests/unit/utils/permissionUtils.spec.js index c14bf5be4..031f2e0c8 100644 --- a/app/frontend/tests/unit/utils/permissionUtils.spec.js +++ b/app/frontend/tests/unit/utils/permissionUtils.spec.js @@ -3,6 +3,7 @@ import { describe, expect, it, vi } from 'vitest'; import { formService } from '~/services'; import { useAuthStore } from '~/store/auth'; +import { useIdpStore } from '~/store/identityProviders'; import { useNotificationStore } from '~/store/notification'; import { FormPermissions, @@ -24,12 +25,6 @@ describe('checkFormSubmit', () => { expect(permissionUtils.checkFormSubmit({ idps: [] })).toBeFalsy(); }); - it('should be true when idps is public', () => { - expect( - permissionUtils.checkFormSubmit({ idps: [IdentityProviders.PUBLIC] }) - ).toBeTruthy(); - }); - it('should be true when permissions is submission creator', () => { expect( permissionUtils.checkFormSubmit({ @@ -109,6 +104,7 @@ describe('preFlightAuth', () => { setActivePinia(createPinia()); const authStore = useAuthStore(); const notificationStore = useNotificationStore(); + const idpStore = useIdpStore(); const mockNext = vi.fn(); const addNotificationSpy = vi.spyOn(notificationStore, 'addNotification'); const alertNavigateSpy = vi.spyOn(notificationStore, 'alertNavigate'); @@ -116,9 +112,16 @@ describe('preFlightAuth', () => { const getSubmissionOptionsSpy = vi.spyOn(formService, 'getSubmissionOptions'); const readFormOptionsSpy = vi.spyOn(formService, 'readFormOptions'); + idpStore.providers = require('../fixtures/identityProviders.json'); + const primaryIdp = idpStore.primaryIdp; + const secondaryIdp = idpStore.providers.find( + (x) => x.active && x.login && !x.primary + ); + beforeEach(() => { authStore.$reset(); notificationStore.$reset(); + //idpStore.$reset(); mockNext.mockReset(); addNotificationSpy.mockReset(); alertNavigateSpy.mockReset(); @@ -146,7 +149,7 @@ describe('preFlightAuth', () => { authStore.authenticated = true; authStore.keycloak = { tokenParsed: { - identity_provider: IdentityProviders.PUBLIC, + identity_provider: 'public', }, }; @@ -172,7 +175,7 @@ describe('preFlightAuth', () => { authStore.authenticated = true; authStore.keycloak = { tokenParsed: { - identity_provider: IdentityProviders.PUBLIC, + identity_provider: 'public', }, }; readFormOptionsSpy.mockImplementation(() => { @@ -197,7 +200,7 @@ describe('preFlightAuth', () => { authStore.authenticated = true; authStore.keycloak = { tokenParsed: { - identity_provider: IdentityProviders.PUBLIC, + identity_provider: 'public', }, }; const addNotificationSpy = vi.spyOn(notificationStore, 'addNotification'); @@ -225,7 +228,7 @@ describe('preFlightAuth', () => { authStore.authenticated = true; authStore.keycloak = { tokenParsed: { - identity_provider: IdentityProviders.PUBLIC, + identity_provider: 'unknown', }, }; const addNotificationSpy = vi.spyOn(notificationStore, 'addNotification'); @@ -253,11 +256,11 @@ describe('preFlightAuth', () => { authStore.authenticated = true; authStore.keycloak = { tokenParsed: { - identity_provider: IdentityProviders.PUBLIC, + identity_provider: 'unknown', }, }; readFormOptionsSpy.mockResolvedValue({ - data: { idpHints: [IdentityMode.PUBLIC] }, + data: { idpHints: [] }, }); await permissionUtils.preFlightAuth({ formId: 'f' }, mockNext); @@ -272,11 +275,11 @@ describe('preFlightAuth', () => { authStore.authenticated = true; authStore.keycloak = { tokenParsed: { - identity_provider: IdentityProviders.IDIR, + identity_provider: primaryIdp.code, }, }; readFormOptionsSpy.mockResolvedValue({ - data: { idpHints: [IdentityProviders.IDIR] }, + data: { idpHints: [primaryIdp.code] }, }); await permissionUtils.preFlightAuth({ formId: 'f' }, mockNext); @@ -291,13 +294,13 @@ describe('preFlightAuth', () => { authStore.authenticated = true; authStore.keycloak = { tokenParsed: { - identity_provider: IdentityProviders.IDIR, + identity_provider: primaryIdp.code, }, }; const addNotificationSpy = vi.spyOn(notificationStore, 'addNotification'); const errorNavigateSpy = vi.spyOn(notificationStore, 'errorNavigate'); readFormOptionsSpy.mockResolvedValue({ - data: { idpHints: [IdentityProviders.BCEIDBASIC] }, + data: { idpHints: [secondaryIdp.code] }, }); await permissionUtils.preFlightAuth({ formId: 'f' }, mockNext); @@ -327,7 +330,7 @@ describe('preFlightAuth', () => { it('should call getSubmissionOptions and login flow with idpHint', async () => { authStore.authenticated = false; getSubmissionOptionsSpy.mockResolvedValue({ - data: { form: { idpHints: [IdentityProviders.IDIR] } }, + data: { form: { idpHints: ['idir'] } }, }); await permissionUtils.preFlightAuth({ submissionId: 's' }, mockNext); diff --git a/app/frontend/tests/unit/views/Login.spec.js b/app/frontend/tests/unit/views/Login.spec.js index 30dbbcc47..4a16c4b1c 100644 --- a/app/frontend/tests/unit/views/Login.spec.js +++ b/app/frontend/tests/unit/views/Login.spec.js @@ -6,13 +6,16 @@ import { nextTick } from 'vue'; import { useAuthStore } from '~/store/auth'; import Login from '~/views/Login.vue'; -import { IdentityProviders } from '~/utils/constants'; +import { useIdpStore } from '~/store/identityProviders'; describe('Login.vue', () => { const pinia = createTestingPinia(); setActivePinia(pinia); const authStore = useAuthStore(pinia); + const idpStore = useIdpStore(pinia); + + idpStore.providers = require('../fixtures/identityProviders.json'); beforeEach(() => { authStore.$reset(); @@ -66,7 +69,7 @@ describe('Login.vue', () => { await nextTick(); - Object.values(IdentityProviders).forEach((idp) => { + Object.values(idpStore.loginIdpHints).forEach((idp) => { const button = wrapper.find(`[data-test="${idp}"]`); expect(button.exists()).toBeTruthy(); });