Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

T#2490/reset password #2577

Merged
merged 2 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading