From b90bbeab7c1435518224496821ff3449476c458d Mon Sep 17 00:00:00 2001
From: Helianthella <git@gumi.ca>
Date: Tue, 22 Dec 2020 00:06:42 -0500
Subject: upgrade to Vue 3, switch to yarn

implies a slight refactor
---
 src/views/Registration.vue | 74 +++++++++++++++++++++-------------------------
 1 file changed, 33 insertions(+), 41 deletions(-)

(limited to 'src/views/Registration.vue')

diff --git a/src/views/Registration.vue b/src/views/Registration.vue
index 38bd5d9..214288b 100644
--- a/src/views/Registration.vue
+++ b/src/views/Registration.vue
@@ -137,19 +137,14 @@
 </template>
 
 <script lang="ts">
-import Vue from "vue"
-import Component from "vue-class-component"
-import VS2 from "vue-script2"
-
-@Component({
-	beforeRouteLeave: (to, from, next) => {
-		next();
-	},
+import { Options, Vue } from "vue-class-component";
+import reCAPTCHA from "@/reCAPTCHA";
 
+@Options({
 	computed: {
 		isRecaptchaAccepted () {
 			// the user already agreed to use reCAPTCHA (loaded)
-			return Reflect.has(self, 'grecaptcha');
+			return reCAPTCHA.isReady;
 		}
 	},
 })
@@ -169,43 +164,40 @@ export default class Registration extends Vue {
 
 	async mounted () {
 		// already loaded (user returned to this page)
-		if (Reflect.has(self, "grecaptcha")) {
+		if (reCAPTCHA.isReady) {
 			await this.$nextTick();
-			(self as any).grecaptcha.render("recaptcha-container", {
+			reCAPTCHA.instance.render("recaptcha-container", {
 				sitekey: process.env.VUE_APP_RECAPTCHA,
 				size: "invisible",
 			});
-			(self as any).grecaptcha.reset();
+			reCAPTCHA.instance.reset();
 		}
 	}
 
 	async start () {
-		(self as any).onRecaptchaLoad = async () => {
+		this.step = -3;
+
+		try {
+			await reCAPTCHA.load();
 			this.step = 1;
 			await this.$nextTick();
-			(this.$refs.email as any).focus();
-		};
-
-		if (Reflect.has(self, "grecaptcha")) {
-			(self as any).onRecaptchaLoad();
-		} else {
-			// load reCAPTCHA
-			VS2.load("https://www.google.com/recaptcha/api.js?onload=onRecaptchaLoad")
-			.catch(() => this.step = -1);
+			(this.$refs.email as HTMLInputElement).focus();
+		} catch (err) {
+			this.step = -1
 		}
 	}
 
 	async checkEmail () {
 		this.step = 2;
 		await this.$nextTick();
-		(this.$refs.user as any).focus();
+		(this.$refs.user as HTMLInputElement).focus();
 	}
 
 	async checkUser () {
 		// TODO: check here whether the username is taken
 		this.step = 3;
 		await this.$nextTick();
-		(this.$refs.password as any).focus();
+		(this.$refs.password as HTMLInputElement).focus();
 	}
 
 	// TODO: this is not compatible with Edge! we must polyfill
@@ -226,22 +218,22 @@ export default class Registration extends Vue {
 	}
 
 	async checkPassword () {
-		const full_hash = await this.sha1(this.user.pwd);
-		const hash_prefix = full_hash.substring(0, 5);
-		const hash_suffix = full_hash.substring(5);
+		const fullHash = await this.sha1(this.user.pwd);
+		const hashPrefix = fullHash.substring(0, 5);
+		const hashSuffix = fullHash.substring(5);
 
-		const req = new Request(`https://api.pwnedpasswords.com/range/${hash_prefix}`, {
+		const req = new Request(`https://api.pwnedpasswords.com/range/${hashPrefix}`, {
 			mode: "cors",
 			cache: "force-cache",
 			referrer: "no-referrer",
 		});
 
-		const raw_response = await fetch(req);
-		const response: string = await raw_response.text();
+		const rawResponse = await fetch(req);
+		const response: string = await rawResponse.text();
 
 		const found = response.split("\n").some(h => {
-			const [hs, times] = h.split(":");
-			return hash_suffix.toUpperCase() === hs.toUpperCase();
+			const [hs,] = h.split(":");
+			return hashSuffix.toUpperCase() === hs.toUpperCase();
 		});
 
 		if (found) {
@@ -253,7 +245,7 @@ export default class Registration extends Vue {
 
 			this.exposed = true;
 			await this.$nextTick();
-			(this.$refs.password as any).focus();
+			(this.$refs.password as HTMLInputElement).focus();
 		} else {
 			this.exposed = false;
 			this.step = 4;
@@ -265,11 +257,11 @@ export default class Registration extends Vue {
 	}
 
 	async create () {
-		(self as any).grecaptcha.execute();
-		let token: string = "";
+		reCAPTCHA.instance.execute();
+		let token = "";
 
 		// the recaptcha API doesn't play nice with Vue
-		while (!(token = (self as any).grecaptcha.getResponse())) {
+		while (!(token = reCAPTCHA.instance.getResponse())) {
 			await this.sleep(1000);
 		}
 
@@ -291,10 +283,10 @@ export default class Registration extends Vue {
 			}),
 		});
 
-		const raw_response = await fetch(req);
-		const response: string = await raw_response.text();
+		const rawResponse = await fetch(req);
+		//const response: string = await rawResponse.text();
 
-		switch (raw_response.status) {
+		switch (rawResponse.status) {
 			// TODO: don't use alerts: embed the error message on the page
 			case 201:
 				this.step = 5;
@@ -311,7 +303,7 @@ export default class Registration extends Vue {
 				this.taken = true;
 				this.step = 2;
 				await this.$nextTick();
-				(this.$refs.user as any).focus();
+				(this.$refs.user as HTMLInputElement).focus();
 				break;
 			case 429:
 				self.alert("Too many requests.\nPlease try again later");
@@ -326,7 +318,7 @@ export default class Registration extends Vue {
 				document.location.reload();
 				break;
 			default:
-				self.alert(`Unknown error: ${raw_response.status}`);
+				self.alert(`Unknown error: ${rawResponse.status}`);
 				document.location.reload();
 				break;
 		}
-- 
cgit v1.2.3-60-g2f50

