diff --git a/app/frontend/src/components/base/BaseAuthButton.vue b/app/frontend/src/components/base/BaseAuthButton.vue
index 8b77ba3f9..944b26f75 100755
--- a/app/frontend/src/components/base/BaseAuthButton.vue
+++ b/app/frontend/src/components/base/BaseAuthButton.vue
@@ -28,8 +28,7 @@ export default {
methods: {
login() {
if (this.keycloakReady) {
- window.location.replace(this.createLoginUrl());
- //window.location.replace(this.createLoginUrl({ idpHint: 'idir' }));
+ window.location.replace(this.createLoginUrl({ idpHint: 'idir' }));
}
},
logout() {
diff --git a/app/frontend/src/components/base/BaseSecure.vue b/app/frontend/src/components/base/BaseSecure.vue
index eab96d49d..40469f3bc 100755
--- a/app/frontend/src/components/base/BaseSecure.vue
+++ b/app/frontend/src/components/base/BaseSecure.vue
@@ -53,8 +53,7 @@ export default {
methods: {
login() {
if (this.keycloakReady) {
- window.location.replace(this.createLoginUrl());
- // window.location.replace(this.createLoginUrl({ idpHint: 'idir' }));
+ window.location.replace(this.createLoginUrl({ idpHint: 'idir' }));
}
},
},
diff --git a/app/frontend/src/components/designer/FormSettings.vue b/app/frontend/src/components/designer/FormSettings.vue
index 3cc9b6935..582a2b30d 100644
--- a/app/frontend/src/components/designer/FormSettings.vue
+++ b/app/frontend/src/components/designer/FormSettings.vue
@@ -35,7 +35,7 @@
:mandatory="false"
:rules="loginRequiredRules"
>
-
+
import(/* webpackChunkName: "create" */ '@/views/form/Create.vue'),
meta: {
- breadcrumbTitle: 'Form Designer'
+ breadcrumbTitle: 'Form Designer',
+ requiresAuth: true,
+ hasLogin: true
},
},
{
@@ -55,7 +57,9 @@ export default function getRouter(basePath = '/') {
name: 'FormDesigner',
component: () => import(/* webpackChunkName: "designer" */ '@/views/form/Design.vue'),
meta: {
- breadcrumbTitle: 'Form Designer'
+ breadcrumbTitle: 'Form Designer',
+ requiresAuth: true,
+ hasLogin: true
},
props: createProps
},
@@ -64,7 +68,9 @@ export default function getRouter(basePath = '/') {
name: 'FormManage',
component: () => import(/* webpackChunkName: "manage" */ '@/views/form/Manage.vue'),
meta: {
- breadcrumbTitle: 'Manage Form'
+ breadcrumbTitle: 'Manage Form',
+ requiresAuth: true,
+ hasLogin: true
},
props: createProps
},
@@ -73,7 +79,9 @@ export default function getRouter(basePath = '/') {
name: 'FormPreview',
component: () => import(/* webpackChunkName: "viewsubmission" */ '@/views/form/Preview.vue'),
meta: {
- breadcrumbTitle: 'Preview Form'
+ breadcrumbTitle: 'Preview Form',
+ requiresAuth: true,
+ hasLogin: true
},
props: createProps
},
@@ -82,7 +90,9 @@ export default function getRouter(basePath = '/') {
name: 'FormSubmissions',
component: () => import(/* webpackChunkName: "submissions" */ '@/views/form/Submissions.vue'),
meta: {
- breadcrumbTitle: 'Submissions'
+ breadcrumbTitle: 'Submissions',
+ requiresAuth: true,
+ hasLogin: true
},
props: createProps
},
@@ -111,7 +121,9 @@ export default function getRouter(basePath = '/') {
name: 'FormTeams',
component: () => import(/* webpackChunkName: "teams" */ '@/views/form/Teams.vue'),
meta: {
- breadcrumbTitle: 'Team Management'
+ breadcrumbTitle: 'Team Management',
+ requiresAuth: true,
+ hasLogin: true
},
props: createProps
},
@@ -120,15 +132,13 @@ export default function getRouter(basePath = '/') {
name: 'FormView',
component: () => import(/* webpackChunkName: "viewsubmission" */ '@/views/form/View.vue'),
meta: {
- breadcrumbTitle: 'View Submission'
+ breadcrumbTitle: 'View Submission',
+ requiresAuth: true,
+ hasLogin: true
},
props: createProps
},
- ],
- meta: {
- requiresAuth: true,
- hasLogin: true
- }
+ ]
},
{
path: '/user',
@@ -193,13 +203,15 @@ export default function getRouter(basePath = '/') {
}
// Force login redirect if not authenticated
+ // Note some pages (Submit and Success) only require auth if the form being loaded is secured
+ // in those cases, see the navigation gaurds in their views for auth loop
if (to.matched.some(route => route.meta.requiresAuth)
&& router.app.$keycloak
&& router.app.$keycloak.ready
&& !router.app.$keycloak.authenticated) {
const redirect = location.origin + basePath + to.path + location.search;
const loginUrl = router.app.$keycloak.createLoginUrl({
- //idpHint: 'idir',
+ idpHint: 'idir',
redirectUri: redirect
});
window.location.replace(loginUrl);
diff --git a/app/frontend/src/store/modules/auth.js b/app/frontend/src/store/modules/auth.js
index 871562698..418fe8f10 100755
--- a/app/frontend/src/store/modules/auth.js
+++ b/app/frontend/src/store/modules/auth.js
@@ -18,7 +18,7 @@ export default {
authenticated: () => Vue.prototype.$keycloak.authenticated,
createLoginUrl: () => options => Vue.prototype.$keycloak.createLoginUrl(options),
createLogoutUrl: () => options => Vue.prototype.$keycloak.createLogoutUrl(options),
- email: () => Vue.prototype.$keycloak.tokenParsed.email,
+ email: () => Vue.prototype.$keycloak.tokenParsed ? Vue.prototype.$keycloak.tokenParsed.email : '',
fullName: () => Vue.prototype.$keycloak.fullName,
hasResourceRoles: (_state, getters) => (resource, roles) => {
if (!getters.authenticated) return false;
diff --git a/app/frontend/src/utils/permissionUtils.js b/app/frontend/src/utils/permissionUtils.js
index 197569886..102377fa1 100644
--- a/app/frontend/src/utils/permissionUtils.js
+++ b/app/frontend/src/utils/permissionUtils.js
@@ -1,4 +1,6 @@
import { FormPermissions, IdentityProviders } from '@/utils/constants';
+import { formService } from '@/services';
+import store from '@/store';
//
// Utility Functions for determining permissions
@@ -45,3 +47,41 @@ export function checkSubmissionView(userForm) {
];
return userForm && userForm.permissions && userForm.permissions.some(p => perms.includes(p));
}
+
+/**
+ * @function determineFormNeedsAuth
+ * When loading a form to fill out, determine if the user needs to log in to submit it
+ * @param {Object} store The vuex store reference
+ * @param {String} formId The form guid
+ * @param {String} submissionId The submission guid
+ * @param {Object} next The routing next object
+ */
+export async function determineFormNeedsAuth(formId, submissionId, next) {
+ // before this view is loaded, determine if this is a public form
+ // if it IS, they don't need to log in. If it's secured, go through auth loop
+ // If authed already skip all this
+ if (!store.getters['auth/authenticated']) {
+ try {
+ // Get this form or submission
+ if (formId) {
+ await formService.readForm(formId);
+ } else if (submissionId) {
+ await formService.getSubmission(submissionId);
+ }
+ } catch (error) {
+ // If there's a 401 trying to get this form, make that user log in
+ if (error.response && error.response.status === 401) {
+ window.location.replace(
+ store.getters['auth/createLoginUrl']({ idpHint: 'idir' })
+ );
+ } else {
+ // Other errors raise an issue
+ store.dispatch('notifications/addNotification', {
+ message: 'An error occurred while loading this form.',
+ consoleError: `Error loading form ${formId} or submission ${submissionId}: ${error}`,
+ });
+ }
+ }
+ }
+ next();
+}
diff --git a/app/frontend/src/utils/transformUtils.js b/app/frontend/src/utils/transformUtils.js
index 0bee5f890..c1eb5b5e1 100644
--- a/app/frontend/src/utils/transformUtils.js
+++ b/app/frontend/src/utils/transformUtils.js
@@ -16,7 +16,7 @@ export function generateIdps({ idps, userType }) {
if (userType === IdentityMode.LOGIN && idps && idps.length) {
identityProviders = identityProviders.concat(idps.map((i) => ({ code: i })));
} else if (userType === IdentityMode.PUBLIC) {
- identityProviders.push(IdentityMode.PUBLIC);
+ identityProviders.push({ code: IdentityMode.PUBLIC });
}
return identityProviders;
}
@@ -33,7 +33,7 @@ export function parseIdps(identityProviders) {
userType: IdentityMode.TEAM,
};
if (identityProviders && identityProviders.length) {
- if (identityProviders[0] === IdentityMode.PUBLIC) {
+ if (identityProviders[0].code === IdentityMode.PUBLIC) {
result.userType = IdentityMode.PUBLIC;
} else {
result.userType = IdentityMode.LOGIN;
diff --git a/app/frontend/src/views/form/Submit.vue b/app/frontend/src/views/form/Submit.vue
index b7cec97d1..9e71fcaf6 100644
--- a/app/frontend/src/views/form/Submit.vue
+++ b/app/frontend/src/views/form/Submit.vue
@@ -5,6 +5,7 @@
diff --git a/app/frontend/src/views/form/Success.vue b/app/frontend/src/views/form/Success.vue
index 26bdc2e5c..56c611bdd 100644
--- a/app/frontend/src/views/form/Success.vue
+++ b/app/frontend/src/views/form/Success.vue
@@ -29,6 +29,7 @@
diff --git a/app/frontend/tests/unit/utils/transformUtils.spec.js b/app/frontend/tests/unit/utils/transformUtils.spec.js
index 413114835..cc3a8afe2 100644
--- a/app/frontend/tests/unit/utils/transformUtils.spec.js
+++ b/app/frontend/tests/unit/utils/transformUtils.spec.js
@@ -21,7 +21,7 @@ describe('generateIdps', () => {
});
it('returns correct values when usertype is public', () => {
- expect(transformUtils.generateIdps({ userType: IdentityMode.PUBLIC })).toEqual([IdentityMode.PUBLIC]);
+ expect(transformUtils.generateIdps({ userType: IdentityMode.PUBLIC })).toEqual([{ code: IdentityMode.PUBLIC }]);
});
});
@@ -41,7 +41,7 @@ describe('parseIdps', () => {
});
it('returns an empty array idps and usertype public when public', () => {
- expect(transformUtils.parseIdps([IdentityMode.PUBLIC])).toEqual({
+ expect(transformUtils.parseIdps([{ code: IdentityMode.PUBLIC }])).toEqual({
idps: [],
userType: IdentityMode.PUBLIC,
});