summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgumi <git@gumi.ca>2020-10-06 10:25:29 -0400
committergumi <git@gumi.ca>2020-10-06 15:25:06 -0400
commit45c8a487106b112e36537321bd14b3f8eb418c07 (patch)
tree69f16967c3902429e2a35e17d0467eeb21a41bec
parentaea2a6ef80d119d930214238289bb42eb6fb656f (diff)
downloadwebsite-45c8a487106b112e36537321bd14b3f8eb418c07.tar.gz
website-45c8a487106b112e36537321bd14b3f8eb418c07.tar.bz2
website-45c8a487106b112e36537321bd14b3f8eb418c07.tar.xz
website-45c8a487106b112e36537321bd14b3f8eb418c07.zip
require the user to opt-in to reCAPTCHA
-rw-r--r--src/views/AccountRecovery.vue74
-rw-r--r--src/views/Registration.vue57
2 files changed, 118 insertions, 13 deletions
diff --git a/src/views/AccountRecovery.vue b/src/views/AccountRecovery.vue
index a9fca20..d78dda2 100644
--- a/src/views/AccountRecovery.vue
+++ b/src/views/AccountRecovery.vue
@@ -1,16 +1,46 @@
<template>
<main>
- <div v-if="step == 1">
+ <div v-if="nextStep != 4">
<h1>Account Recovery</h1>
<p>Use this form if you forgot your username or password.</p>
<p>If it matches any account we have on file you will receive a message containing the list of your account usernames
along with a password reset link, should you wish to reset your password.</p>
</div>
+ <div v-if="step == -3">
+ <h1>reCAPTCHA privacy notice</h1>
+ <p>This page uses Google reCAPTCHA. By continuing, you agree to use reCAPTCHA, which may register tracking cookies in your browser.</p>
+ <p>You may review the Google Privacy Policy at <a href="https://policies.google.com/privacy">https://policies.google.com/privacy</a>.</p>
+
+ <button @click="start">I understand and wish to proceed</button>
+ <br><br>
+
+ <h1>Proceeding without reCAPTCHA</h1>
+ <p>If you would rather not use reCAPTCHA, you may recover your account by contacting us by email.</p>
+ <br>
+ <address>support@themanaworld.org</address>
+ </div>
+
+ <div v-if="step == -4">
+ <h1>Loading...</h1>
+ <p>Please wait while reCAPTCHA is loading...</p>
+ <br><br>
+
+ <h1>Proceeding without reCAPTCHA</h1>
+ <p>If you would rather not use reCAPTCHA, you may recover your account by contacting us by email.</p>
+ <br>
+ <address>support@themanaworld.org</address>
+ </div>
+
<div v-if="step == -1">
<h1>reCAPTCHA could not be loaded</h1>
<p>This page requires reCAPTCHA but something prevents it from loading.
If you are using an ad blocker or tracker blocker please whitelist this page and refresh to continue.</p>
+
+ <h1>Proceeding without reCAPTCHA</h1>
+ <p>If you would rather not use reCAPTCHA, you may recover your account by contacting us by email.</p>
+ <br>
+ <address>support@themanaworld.org</address>
</div>
<div v-if="step == 1">
@@ -125,17 +155,17 @@
:data-sitekey="recaptcha_key"
data-size="invisible">
</div>
-
- <script2 src="https://www.google.com/recaptcha/api.js" unload="Reflect.deleteProperty(self, 'grecaptcha')"/>
</main>
</template>
<script lang="ts">
import { Vue, Component, Prop } from "vue-property-decorator"
+import VS2 from "vue-script2"
@Component
export default class Recovery extends Vue {
- step = 1; // no Begin button here
+ step = -3; // ask to use reCAPTCHA
+ nextStep = 1; // first step after reCAPTCHA confirmation
notFound = false; // no accounts found
visible = false; // password is visible
exposed = false; // password has been breached
@@ -159,20 +189,52 @@ export default class Recovery extends Vue {
if (token.length > 1) {
if (/^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$/i.test(token)) {
this.emailToken = token;
- this.step = 4;
+ this.nextStep = 4; // with token: enter username to reset
} else {
- this.step = -2;
+ this.step = -2; // invalid token
+ return;
}
}
// already loaded (user returned to this page)
if (Reflect.has(self, "grecaptcha")) {
+ if (this.step == -3) {
+ this.step = this.nextStep;
+ }
+
await this.$nextTick();
(self as any).grecaptcha.render("recaptcha-container", {
sitekey: process.env.VUE_APP_RECAPTCHA,
size: "invisible",
});
(self as any).grecaptcha.reset();
+
+ if (this.step == 1) {
+ (this.$refs.email as any).focus();
+ } else if (this.step == 4) {
+ (this.$refs.user as any).focus();
+ }
+ }
+ }
+
+ async start () {
+ (self as any).onRecaptchaLoad = async () => {
+ this.step = this.nextStep;
+ await this.$nextTick();
+
+ if (this.step == 1) {
+ (this.$refs.email as any).focus();
+ } else if (this.step == 4) {
+ (this.$refs.user 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);
}
}
diff --git a/src/views/Registration.vue b/src/views/Registration.vue
index 41ebfeb..54bee98 100644
--- a/src/views/Registration.vue
+++ b/src/views/Registration.vue
@@ -7,7 +7,34 @@
<div style="background-color: #FFAAAA; text-align: center; border: 1px solid #BB5555; margin-bottom: 10px; text-color: white;">
<b>The apocalypse is upon us.</b> Due the Doomsday Event, during event times, powerful monsters may be found in otherwise safe areas, and sometimes even inside towns. <a href="https://forums.themanaworld.org/viewtopic.php?p=160290#p160290">Read more details here &#xffeb;</a>
</div>
- <button v-if="!step" @click="start">Begin!</button>
+ <button v-if="!step" @click="isRecaptchaAccepted ? start() : step = -2">Begin!</button>
+
+ <div v-if="step == -2">
+ <h1>reCAPTCHA privacy notice</h1>
+ <p>This page uses Google reCAPTCHA. By continuing, you agree to use reCAPTCHA, which may register tracking cookies in your browser.</p>
+ <p>You may review the Google Privacy Policy at <a href="https://policies.google.com/privacy">https://policies.google.com/privacy</a>.</p>
+
+ <button @click="start">I understand and wish to proceed</button>
+ <br><br>
+
+ <h1>Registering without reCAPTCHA</h1>
+ <p>If you would rather not use reCAPTCHA, you may register by contacting us by email.</p>
+ <p>We will create a new account for you and associate it with the email address that you used to contact us.</p>
+ <br>
+ <address>registration@themanaworld.org</address>
+ </div>
+
+ <div v-if="step == -3">
+ <h1>Loading...</h1>
+ <p>Please wait while reCAPTCHA is loading...</p>
+ <br><br>
+
+ <h1>Registering without reCAPTCHA</h1>
+ <p>If you would rather not use reCAPTCHA, you may register by contacting us by email.</p>
+ <p>We will create a new account for you and associate it with the email address that you used to contact us.</p>
+ <br>
+ <address>registration@themanaworld.org</address>
+ </div>
<div v-if="step == -1">
<h1>reCAPTCHA could not be loaded</h1>
@@ -106,19 +133,25 @@
:data-sitekey="recaptcha_key"
data-size="invisible">
</div>
-
- <script2 src="https://www.google.com/recaptcha/api.js" unload="Reflect.deleteProperty(self, 'grecaptcha')"/>
</main>
</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();
- }
+ },
+
+ computed: {
+ isRecaptchaAccepted () {
+ // the user already agreed to use reCAPTCHA (loaded)
+ return Reflect.has(self, 'grecaptcha');
+ }
+ },
})
export default class Registration extends Vue {
step = 0;
@@ -147,9 +180,19 @@ export default class Registration extends Vue {
}
async start () {
- this.step = Reflect.has(self, "grecaptcha") ? 1 : -1;
- await this.$nextTick();
- (this.$refs.email as any).focus();
+ (self as any).onRecaptchaLoad = async () => {
+ 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);
+ }
}
async checkEmail () {