Skip to content

Commit

Permalink
Merge pull request #2577 from NationalSecurityAgency/t#2490/reset_pas…
Browse files Browse the repository at this point in the history
…sword

T#2490/reset password
  • Loading branch information
dwalizer authored Jun 12, 2024
2 parents 32f7916 + 2fa0846 commit 7be1d94
Show file tree
Hide file tree
Showing 11 changed files with 454 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ jobs:
- name: Run Cypress tests
run: |
cd e2e-tests
../.github/scripts/runSubsetOfCypressTests.sh -t 10 -c ${{ matrix.container }} -f 'projects_crud|/skills_table_spec|/skill_reuse_spec|quiz_creation|question_def|metrics-reUsedData_spec|quiz_and_survey|quiz_runs|quiz_skill_assignment|quiz_read|quiz_role|quiz_settings|quiz_skills-in_project_reuse|client-display_quiz_spec|client-display_quiz_theme_spec|client-display_quiz_visual_spec|client-display_run_quiz_spec|run_survey_spec|quiz_skills-catalog_spec|/inception|user_actions|configure-skill-expiration_spec|skill-expiration-table_spec|configure_video_spec|configure_video_features_spec|configure_skill_video_self_report_spec|configure_video_validation_spec|handle_video_without_duration_spec|client_display_video_on_subject_page_spec|client_display_video_on_skill_page_spec|/skills_spec|/users_spec|/subjects_spec|/levels_management_spec|/skills_group_spec|/skills_group_modal_spec|/move-skills/|/badges_spec|/skill-reuse/skill_reuse/|/catalog/|/project_settings_spec|/icon_manager_spec|/not_found_spec|my-usage_spec|/error_pages_spec|/add_skills_to_badge_spec|/tag-skills|/settings_spec|/client-display/|/learning-path/|/copy_project_spec|/project_errors_spec|/selfReport-approvalHistory_spec|/approver|/manage-my-projects_spec|/accessibility|/community/|/metrics/projectMetrics|/metrics/skillMetrics_spec|/metrics/subjectMetrics_spec|/projects_invite_only_spec|/app_features_spec|/breadcrumb_spec|/contact|/cross-project_spec|/discoverable_proj_invite_spec|/login_spec|/markdown_spec/metrics/multipleProjectMetrics_empty_spec|/metrics/multipleProjectMetrics_spec|/my-progress_breadcrumb_spec|/my-progress_spec|/my-progress-badges_spec|/navigation_spec|/progress_and_ranking_disabled_spec|/project_expiration_spec|performedSkills_table_spec|/projects_admin_management_spec|/projects_modal_management_spec|/projects_modal_validation_spec|/projects_spec|/rootUser_pinUnpin_spec|/save_state_spec'
../.github/scripts/runSubsetOfCypressTests.sh -t 10 -c ${{ matrix.container }} -f 'projects_crud|/skills_table_spec|/skill_reuse_spec|quiz_creation|question_def|metrics-reUsedData_spec|quiz_and_survey|quiz_runs|quiz_skill_assignment|quiz_read|quiz_role|quiz_settings|quiz_skills-in_project_reuse|client-display_quiz_spec|client-display_quiz_theme_spec|client-display_quiz_visual_spec|client-display_run_quiz_spec|run_survey_spec|quiz_skills-catalog_spec|/inception|user_actions|configure-skill-expiration_spec|skill-expiration-table_spec|configure_video_spec|configure_video_features_spec|configure_skill_video_self_report_spec|configure_video_validation_spec|handle_video_without_duration_spec|client_display_video_on_subject_page_spec|client_display_video_on_skill_page_spec|/skills_spec|/users_spec|/subjects_spec|/levels_management_spec|/skills_group_spec|/skills_group_modal_spec|/move-skills/|/badges_spec|/skill-reuse/skill_reuse/|/catalog/|/project_settings_spec|/icon_manager_spec|/not_found_spec|my-usage_spec|password_reset_spec|/error_pages_spec|/add_skills_to_badge_spec|/tag-skills|/settings_spec|/client-display/|/learning-path/|/copy_project_spec|/project_errors_spec|/selfReport-approvalHistory_spec|/approver|/manage-my-projects_spec|/accessibility|/community/|/metrics/projectMetrics|/metrics/skillMetrics_spec|/metrics/subjectMetrics_spec|/projects_invite_only_spec|/app_features_spec|/breadcrumb_spec|/contact|/cross-project_spec|/discoverable_proj_invite_spec|/login_spec|/markdown_spec/metrics/multipleProjectMetrics_empty_spec|/metrics/multipleProjectMetrics_spec|/my-progress_breadcrumb_spec|/my-progress_spec|/my-progress-badges_spec|/navigation_spec|/progress_and_ranking_disabled_spec|/project_expiration_spec|performedSkills_table_spec|/projects_admin_management_spec|/projects_modal_management_spec|/projects_modal_validation_spec|/projects_spec|/rootUser_pinUnpin_spec|/save_state_spec'
cd ..
env:
ELECTRON_EXTRA_LAUNCH_ARGS: '--disable-gpu'
Expand Down
2 changes: 1 addition & 1 deletion dashboard-prime/src/components/access/Login.vue
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ const oAuth2Login = (registrationId) => {
<label for="inputPassword" class="flex">Password</label>
<div class="flex-1 text-right">
<small class="text-muted">
<router-link data-cy="forgotPassword" to="/">Forgot Password?</router-link>
<router-link data-cy="forgotPassword" :to="{ name:'ForgotPassword' }">Forgot Password?</router-link>
<!-- <b-link tabindex="0" @click="forgotPassword" data-cy="forgotPassword"-->
<!-- >Forgot Password?</b-link-->
<!-- >-->
Expand Down
108 changes: 108 additions & 0 deletions dashboard-prime/src/components/access/RequestPasswordReset.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<script setup>
import { computed, onMounted, ref, watch } from 'vue';
import { useRouter } from 'vue-router';
import { useForm } from 'vee-validate';
import { useAppConfig } from '@/common-components/stores/UseAppConfig.js';
import * as yup from 'yup';
import Logo1 from '@/components/brand/Logo1.vue';
import AccessService from '@/components/access/AccessService.js';
import { string } from 'yup';
const router = useRouter()
const appConfig = useAppConfig()
const username = ref('');
const serverError = ref('');
onMounted(() => {
AccessService.isResetSupported().then((response) => {
if (response === false) {
router.replace({ name: 'ResetNotSupportedPage' });
}
});
})
watch(username, (newVal, oldVal) => {
if (newVal.trim() !== oldVal.trim()) {
serverError.value = '';
}
})
const disabled = computed(() => {
return !meta.value.valid || serverError.value !== '';
})
const schema = yup.object().shape({
username: string().required().email().min(appConfig.minUsernameLength).label('Email Address'),
})
const { values, meta, handleSubmit, validate, errors } = useForm({
validationSchema: schema,
initialValues: {
username: '',
}
})
const reset = (username) => {
AccessService.requestPasswordReset(username).then((response) => {
serverError.value = '';
if (response.success) {
router.push({ name: 'RequestResetConfirmation', params: { email: username } });
}
}).catch((err) => {
if (err && err.response && err.response.data && err.response.data.explanation) {
serverError.value = err.response.data.explanation;
} else {
serverError.value = `Password reset request failed due to ${err.response.status}`;
}
});
}
const resetPassword = handleSubmit((values) => {
reset(values.username)
});
</script>

<template>
<div>
<div class="grid justify-content-center text-center">
<div class="col md:col-8 lg:col-7 xl:col-4 mt-3" style="min-width: 20rem;">
<div class="mt-5">
<logo1 />
<div class="text-3xl mt-4 text-primary">Reset Password For SkillTree Dashboard</div>
</div>
<Card class="mt-3 text-left">
<template #content>
<div class="w-full">
<SkillsTextInput
label="Email Address"
size="small"
:is-required="true"
@keyup.enter="resetPassword"
placeholder="Enter email"
v-model="username"
data-cy="forgotPasswordEmail"
id="username"
name="username"/>
</div>
<small class="text-danger text-red-500" v-if="serverError" data-cy="resetFailedError" role="alert">{{ serverError }}</small>
<div class="flex justify-content-end mt-2">
<SkillsButton variant="outline-success"
label="Reset Password"
icon="fas fa-arrow-circle-right"
@click="resetPassword"
:disabled="disabled"
data-cy="resetPassword">
</SkillsButton>
</div>
</template>
</Card>
</div>
</div>
</div>
</template>

<style scoped>
</style>
58 changes: 58 additions & 0 deletions dashboard-prime/src/components/access/RequestResetConfirmation.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<script setup>
import { onMounted, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import Logo1 from '@/components/brand/Logo1.vue';
const router = useRouter();
const route = useRoute();
const email = ref(route.params.email);
const timer = ref(-1);
onMounted(() => {
timer.value = 10;
});
watch(timer, (value) => {
if (value > 0) {
setTimeout(() => {
timer.value -= 1;
}, 1000);
} else {
router.push({ name: 'Login' });
}
})
</script>

<template>
<div>
<div class="grid justify-content-center text-center" data-cy="resetRequestConfirmation">
<div class="col md:col-8 lg:col-7 xl:col-4 mt-3" style="min-width: 20rem;">
<div class="mt-5">
<logo1 />
<div class="text-3xl mt-4 text-primary">Reset Password For SkillTree Dashboard</div>
</div>
<Card class="mt-3 text-left">
<template #content>
<p>A password reset link has been sent to <span class="text-primary font-weight-bold">{{ email }}</span>. You will be forwarded to the login page in {{ timer }} seconds.</p>
<div class="flex justify-content-center mt-2">
<router-link :to="{ name: 'Login' }">
<SkillsButton icon="fas fa-sign-in-alt"
outlined
size="small"
data-cy="loginPage"
id="loginPageBtn"
label="Return to Login Page">
</SkillsButton>
</router-link>
</div>
</template>
</Card>
</div>
</div>
</div>
</template>

<style scoped>
</style>
56 changes: 56 additions & 0 deletions dashboard-prime/src/components/access/ResetConfirmation.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<script setup>
import { onMounted, ref, watch } from 'vue';
import { useRouter } from 'vue-router';
import Logo1 from '@/components/brand/Logo1.vue';
const router = useRouter();
const timer = ref(-1);
onMounted(() => {
timer.value = 10;
});
watch(timer, (value) => {
if (value > 0) {
setTimeout(() => {
timer.value -= 1;
}, 1000);
} else {
router.push({ name: 'Login' });
}
})
</script>

<template>
<div>
<div class="grid justify-content-center text-center" data-cy="resetConfirmation">
<div class="col md:col-8 lg:col-7 xl:col-4 mt-3" style="min-width: 20rem;">
<div class="mt-5">
<logo1 />
<div class="text-3xl mt-4 text-primary">Password Successfully Reset!</div>
</div>
<Card class="mt-3 text-left">
<template #content>
<p>Your password has been successfully reset! You will be forwarded to the login page in {{ timer }} seconds.</p>
<div class="flex justify-content-center mt-2">
<router-link :to="{ name: 'Login' }">
<SkillsButton icon="fas fa-sign-in-alt"
outlined
size="small"
data-cy="loginPage"
id="loginPageBtn"
label="Return to Login Page">
</SkillsButton>
</router-link>
</div>
</template>
</Card>
</div>
</div>
</div>
</template>

<style scoped>
</style>
26 changes: 26 additions & 0 deletions dashboard-prime/src/components/access/ResetNotSupportedPage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<script setup>
import Logo1 from '@/components/brand/Logo1.vue';
</script>

<template>
<div>
<div class="grid justify-content-center text-center" data-cy="resetNotSupported">
<div class="col md:col-8 lg:col-7 xl:col-5 mt-3" style="min-width: 20rem;">
<div class="mt-5">
<logo1 />
<div class="text-3xl mt-4 text-primary">Password Reset not currently enabled</div>
</div>
<Card class="mt-3 text-left">
<template #content>
Password Reset is not currently enabled on this system. Please contact your SkillTree administrator. Return to the <router-link :to="{ name: 'Login' }" data-cy="loginPage">login page</router-link>?
</template>
</Card>
</div>
</div>
</div>
</template>

<style scoped>
</style>
Loading

0 comments on commit 7be1d94

Please sign in to comment.