web/satellite: migrate ForgotPassword component to use SFC composition api
Change-Id: I9a69e95183efa79aa13b469091c452b6074b4d69
This commit is contained in:
parent
3336a24c5d
commit
7cf840ee98
@ -38,7 +38,7 @@
|
|||||||
<SelectedCheckIcon />
|
<SelectedCheckIcon />
|
||||||
<span class="forgot-area__expand__dropdown__item__name">{{ satelliteName }}</span>
|
<span class="forgot-area__expand__dropdown__item__name">{{ satelliteName }}</span>
|
||||||
</li>
|
</li>
|
||||||
<li v-for="sat in partneredSatellites" :key="sat.id">
|
<li v-for="sat in partneredSatellites" :key="sat.name">
|
||||||
<a class="forgot-area__expand__dropdown__item" :href="sat.address + '/forgot-password'">
|
<a class="forgot-area__expand__dropdown__item" :href="sat.address + '/forgot-password'">
|
||||||
{{ sat.name }}
|
{{ sat.name }}
|
||||||
</a>
|
</a>
|
||||||
@ -94,8 +94,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import { Component, Vue } from 'vue-property-decorator';
|
import { computed, onMounted, reactive, ref } from 'vue';
|
||||||
import VueRecaptcha from 'vue-recaptcha';
|
import VueRecaptcha from 'vue-recaptcha';
|
||||||
import VueHcaptcha from '@hcaptcha/vue-hcaptcha';
|
import VueHcaptcha from '@hcaptcha/vue-hcaptcha';
|
||||||
|
|
||||||
@ -105,6 +105,7 @@ import { PartneredSatellite } from '@/types/common';
|
|||||||
import { Validator } from '@/utils/validation';
|
import { Validator } from '@/utils/validation';
|
||||||
import { MetaUtils } from '@/utils/meta';
|
import { MetaUtils } from '@/utils/meta';
|
||||||
import { AnalyticsHttpApi } from '@/api/analytics';
|
import { AnalyticsHttpApi } from '@/api/analytics';
|
||||||
|
import { useNotify, useRouter, useStore } from '@/utils/hooks';
|
||||||
|
|
||||||
import VInput from '@/components/common/VInput.vue';
|
import VInput from '@/components/common/VInput.vue';
|
||||||
import VButton from '@/components/common/VButton.vue';
|
import VButton from '@/components/common/VButton.vue';
|
||||||
@ -115,173 +116,145 @@ import CloseIcon from '@/../static/images/notifications/closeSmall.svg';
|
|||||||
import SelectedCheckIcon from '@/../static/images/common/selectedCheck.svg';
|
import SelectedCheckIcon from '@/../static/images/common/selectedCheck.svg';
|
||||||
import BottomArrowIcon from '@/../static/images/common/lightBottomArrow.svg';
|
import BottomArrowIcon from '@/../static/images/common/lightBottomArrow.svg';
|
||||||
|
|
||||||
// @vue/component
|
const store = useStore();
|
||||||
@Component({
|
const notify = useNotify();
|
||||||
components: {
|
const nativeRouter = useRouter();
|
||||||
VInput,
|
const router = reactive(nativeRouter);
|
||||||
VButton,
|
|
||||||
BottomArrowIcon,
|
|
||||||
SelectedCheckIcon,
|
|
||||||
LogoIcon,
|
|
||||||
InfoIcon,
|
|
||||||
CloseIcon,
|
|
||||||
VueRecaptcha,
|
|
||||||
VueHcaptcha,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
export default class ForgotPassword extends Vue {
|
|
||||||
private email = '';
|
|
||||||
private emailError = '';
|
|
||||||
private captchaResponseToken = '';
|
|
||||||
private isLoading = false;
|
|
||||||
private isPasswordResetExpired = false;
|
|
||||||
private isMessageShowing = true;
|
|
||||||
|
|
||||||
private readonly recaptchaEnabled: boolean = MetaUtils.getMetaContent('login-recaptcha-enabled') === 'true';
|
const recaptchaEnabled: boolean = MetaUtils.getMetaContent('login-recaptcha-enabled') === 'true';
|
||||||
private readonly recaptchaSiteKey: string = MetaUtils.getMetaContent('login-recaptcha-site-key');
|
const recaptchaSiteKey: string = MetaUtils.getMetaContent('login-recaptcha-site-key');
|
||||||
private readonly hcaptchaEnabled: boolean = MetaUtils.getMetaContent('login-hcaptcha-enabled') === 'true';
|
const hcaptchaEnabled: boolean = MetaUtils.getMetaContent('login-hcaptcha-enabled') === 'true';
|
||||||
private readonly hcaptchaSiteKey: string = MetaUtils.getMetaContent('login-hcaptcha-site-key');
|
const hcaptchaSiteKey: string = MetaUtils.getMetaContent('login-hcaptcha-site-key');
|
||||||
|
const auth: AuthHttpApi = new AuthHttpApi();
|
||||||
|
const analytics: AnalyticsHttpApi = new AnalyticsHttpApi();
|
||||||
|
const loginPath: string = RouteConfig.Login.path;
|
||||||
|
|
||||||
private readonly auth: AuthHttpApi = new AuthHttpApi();
|
const email = ref<string>('');
|
||||||
|
const emailError = ref<string>('');
|
||||||
|
const captchaResponseToken = ref<string>('');
|
||||||
|
const isLoading = ref<boolean>(false);
|
||||||
|
const isPasswordResetExpired = ref<boolean>(false);
|
||||||
|
const isMessageShowing = ref<boolean>(true);
|
||||||
|
const isDropdownShown = ref<boolean>(false);
|
||||||
|
const captcha = ref<VueRecaptcha | VueHcaptcha>();
|
||||||
|
|
||||||
public readonly analytics: AnalyticsHttpApi = new AnalyticsHttpApi();
|
/**
|
||||||
|
* Name of the current satellite.
|
||||||
|
*/
|
||||||
|
const satelliteName = computed((): string => {
|
||||||
|
return store.state.appStateModule.satelliteName;
|
||||||
|
});
|
||||||
|
|
||||||
// tardigrade logic
|
/**
|
||||||
public isDropdownShown = false;
|
* Information about partnered satellites, including name and signup link.
|
||||||
|
*/
|
||||||
|
const partneredSatellites = computed((): PartneredSatellite[] => {
|
||||||
|
return store.state.appStateModule.partneredSatellites;
|
||||||
|
});
|
||||||
|
|
||||||
public readonly loginPath: string = RouteConfig.Login.path;
|
/**
|
||||||
|
* Close the expiry message banner.
|
||||||
public $refs!: {
|
*/
|
||||||
captcha: VueRecaptcha | VueHcaptcha;
|
function closeMessage() {
|
||||||
};
|
isMessageShowing.value = false;
|
||||||
|
|
||||||
public mounted(): void {
|
|
||||||
this.isPasswordResetExpired = this.$route.query.expired === 'true';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the expiry message banner.
|
|
||||||
*/
|
|
||||||
public closeMessage() {
|
|
||||||
this.isMessageShowing = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the email field to the given value.
|
|
||||||
*/
|
|
||||||
public setEmail(value: string): void {
|
|
||||||
this.email = value.trim();
|
|
||||||
this.emailError = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Name of the current satellite.
|
|
||||||
*/
|
|
||||||
public get satelliteName(): string {
|
|
||||||
return this.$store.state.appStateModule.satelliteName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Information about partnered satellites, including name and signup link.
|
|
||||||
*/
|
|
||||||
public get partneredSatellites(): PartneredSatellite[] {
|
|
||||||
return this.$store.state.appStateModule.partneredSatellites;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Toggles satellite selection dropdown visibility (Tardigrade).
|
|
||||||
*/
|
|
||||||
public toggleDropdown(): void {
|
|
||||||
this.isDropdownShown = !this.isDropdownShown;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Closes satellite selection dropdown (Tardigrade).
|
|
||||||
*/
|
|
||||||
public closeDropdown(): void {
|
|
||||||
this.isDropdownShown = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles captcha verification response.
|
|
||||||
*/
|
|
||||||
public onCaptchaVerified(response: string): void {
|
|
||||||
this.captchaResponseToken = response;
|
|
||||||
this.onSendConfigurations();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles captcha error.
|
|
||||||
*/
|
|
||||||
public onCaptchaError(): void {
|
|
||||||
this.captchaResponseToken = '';
|
|
||||||
this.$notify.error('The captcha encountered an error. Please try again.', null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends recovery password email.
|
|
||||||
*/
|
|
||||||
public async onSendConfigurations(): Promise<void> {
|
|
||||||
let activeElement = document.activeElement;
|
|
||||||
if (activeElement && activeElement.id === 'resetDropdown') return;
|
|
||||||
|
|
||||||
if (this.isLoading || !this.validateFields()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.$refs.captcha && !this.captchaResponseToken) {
|
|
||||||
this.$refs.captcha.execute();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.isDropdownShown) {
|
|
||||||
this.isDropdownShown = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.isLoading = true;
|
|
||||||
|
|
||||||
try {
|
|
||||||
await this.auth.forgotPassword(this.email, this.captchaResponseToken);
|
|
||||||
await this.$notify.success('Please look for instructions in your email');
|
|
||||||
} catch (error) {
|
|
||||||
await this.$notify.error(error.message, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$refs.captcha?.reset();
|
|
||||||
this.captchaResponseToken = '';
|
|
||||||
this.isLoading = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Changes location to Login route.
|
|
||||||
*/
|
|
||||||
public onBackToLoginClick(): void {
|
|
||||||
this.analytics.pageVisit(RouteConfig.Login.path);
|
|
||||||
this.$router.push(RouteConfig.Login.path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Redirects to storj.io homepage.
|
|
||||||
*/
|
|
||||||
public onLogoClick(): void {
|
|
||||||
const homepageURL = MetaUtils.getMetaContent('homepage-url');
|
|
||||||
window.location.href = homepageURL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether the email address is properly structured.
|
|
||||||
*/
|
|
||||||
private validateFields(): boolean {
|
|
||||||
const isEmailValid = Validator.email(this.email);
|
|
||||||
|
|
||||||
if (!isEmailValid) {
|
|
||||||
this.emailError = 'Invalid Email';
|
|
||||||
}
|
|
||||||
|
|
||||||
return isEmailValid;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the email field to the given value.
|
||||||
|
*/
|
||||||
|
function setEmail(value: string): void {
|
||||||
|
email.value = value.trim();
|
||||||
|
emailError.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles satellite selection dropdown visibility (Partnered).
|
||||||
|
*/
|
||||||
|
function toggleDropdown(): void {
|
||||||
|
isDropdownShown.value = !isDropdownShown.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes satellite selection dropdown (Partnered).
|
||||||
|
*/
|
||||||
|
function closeDropdown(): void {
|
||||||
|
isDropdownShown.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles captcha verification response.
|
||||||
|
*/
|
||||||
|
function onCaptchaVerified(response: string): void {
|
||||||
|
captchaResponseToken.value = response;
|
||||||
|
onSendConfigurations();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles captcha error.
|
||||||
|
*/
|
||||||
|
function onCaptchaError(): void {
|
||||||
|
captchaResponseToken.value = '';
|
||||||
|
notify.error('The captcha encountered an error. Please try again.', null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends recovery password email.
|
||||||
|
*/
|
||||||
|
async function onSendConfigurations(): Promise<void> {
|
||||||
|
let activeElement = document.activeElement;
|
||||||
|
if (activeElement && activeElement.id === 'resetDropdown') return;
|
||||||
|
|
||||||
|
if (isLoading.value || !validateFields()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (captcha.value && !captchaResponseToken.value) {
|
||||||
|
captcha.value.execute();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDropdownShown.value) {
|
||||||
|
closeDropdown();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
isLoading.value = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await auth.forgotPassword(email.value, captchaResponseToken.value);
|
||||||
|
await notify.success('Please look for instructions in your email');
|
||||||
|
} catch (error) {
|
||||||
|
await notify.error(error.message, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
captcha.value?.reset();
|
||||||
|
captchaResponseToken.value = '';
|
||||||
|
isLoading.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirects to storj.io homepage.
|
||||||
|
*/
|
||||||
|
function onLogoClick(): void {
|
||||||
|
window.location.href = MetaUtils.getMetaContent('homepage-url');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the email address is properly structured.
|
||||||
|
*/
|
||||||
|
function validateFields(): boolean {
|
||||||
|
const isEmailValid = Validator.email(email.value);
|
||||||
|
|
||||||
|
if (!isEmailValid) {
|
||||||
|
emailError.value = 'Invalid Email';
|
||||||
|
}
|
||||||
|
|
||||||
|
return isEmailValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted((): void => {
|
||||||
|
isPasswordResetExpired.value = router.currentRoute.query.expired === 'true';
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
Loading…
Reference in New Issue
Block a user