Warn when registering with email containing uppercase characters

Closes #884 and #803

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel
2021-11-16 11:38:17 +01:00
parent be1664ec85
commit d291a83cc9
6 changed files with 125 additions and 29 deletions

View File

@@ -1251,5 +1251,6 @@
"Approve member": "Approve member",
"Reject member": "Reject member",
"The membership request from {profile} was rejected": "The membership request from {profile} was rejected",
"The member was approved": "The member was approved"
"The member was approved": "The member was approved",
"Emails usually don't contain capitals, make sure you haven't made a typo.": "Emails usually don't contain capitals, make sure you haven't made a typo."
}

View File

@@ -1355,5 +1355,6 @@
"Approve member": "Approuver le ou la membre",
"Reject member": "Rejeter le ou la membre",
"The membership request from {profile} was rejected": "La demande d'adhésion de {profile} a été rejetée",
"The member was approved": "Le ou la membre a été approuvée"
"The member was approved": "Le ou la membre a été approuvée",
"Emails usually don't contain capitals, make sure you haven't made a typo.": "Les emails ne contiennent d'ordinaire pas de capitales, assurez-vous de n'avoir pas fait de faute de frappe."
}

5
js/src/types/apollo.ts Normal file
View File

@@ -0,0 +1,5 @@
import { GraphQLError } from "graphql/error/GraphQLError";
export class AbsintheGraphQLError extends GraphQLError {
readonly field: string | undefined;
}

View File

@@ -83,8 +83,8 @@
<form v-on:submit.prevent="submit()">
<b-field
:label="$t('Email')"
:type="errors.email ? 'is-danger' : null"
:message="errors.email"
:type="errorEmailType"
:message="errorEmailMessages"
label-for="email"
>
<b-input
@@ -100,8 +100,8 @@
<b-field
:label="$t('Password')"
:type="errors.password ? 'is-danger' : null"
:message="errors.password"
:type="errorPasswordType"
:message="errorPasswordMessages"
label-for="password"
>
<b-input
@@ -178,12 +178,6 @@
<auth-providers :oauthProviders="config.auth.oauthProviders" />
</div>
</form>
<div v-if="errors.length > 0">
<b-message type="is-danger" v-for="error in errors" :key="error">{{
error
}}</b-message>
</div>
</div>
</div>
</section>
@@ -191,13 +185,18 @@
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
import { Component, Prop, Vue, Watch } from "vue-property-decorator";
import { CREATE_USER } from "../../graphql/user";
import RouteName from "../../router/name";
import { IConfig } from "../../types/config.model";
import { CONFIG } from "../../graphql/config";
import Subtitle from "../../components/Utils/Subtitle.vue";
import AuthProviders from "../../components/User/AuthProviders.vue";
import { AbsintheGraphQLError } from "../../types/apollo";
type errorType = "is-danger" | "is-warning";
type errorMessage = { type: errorType; message: string };
type credentials = { email: string; password: string; locale: string };
@Component({
components: { Subtitle, AuthProviders },
@@ -218,13 +217,14 @@ export default class Register extends Vue {
@Prop({ type: String, required: false, default: "" }) password!: string;
credentials = {
credentials: credentials = {
email: this.email,
password: this.password,
locale: "en",
};
errors: string[] = [];
emailErrors: errorMessage[] = [];
passwordErrors: errorMessage[] = [];
sendingForm = false;
@@ -245,7 +245,8 @@ export default class Register extends Vue {
this.sendingForm = true;
this.credentials.locale = this.$i18n.locale;
try {
this.errors = [];
this.emailErrors = [];
this.passwordErrors = [];
await this.$apollo.mutate({
mutation: CREATE_USER,
@@ -257,17 +258,67 @@ export default class Register extends Vue {
params: { email: this.credentials.email },
});
} catch (error: any) {
console.error(error);
this.errors = error.graphQLErrors.reduce(
(acc: string[], localError: any) => {
acc.push(localError.message);
return acc;
},
[]
error.graphQLErrors.forEach(
({ field, message }: AbsintheGraphQLError) => {
switch (field) {
case "email":
this.emailErrors.push({
type: "is-danger" as errorType,
message: message[0] as string,
});
break;
case "password":
this.passwordErrors.push({
type: "is-danger" as errorType,
message: message[0] as string,
});
break;
default:
}
}
);
this.sendingForm = false;
}
}
@Watch("credentials", { deep: true })
watchCredentials(credentials: credentials): void {
if (credentials.email !== credentials.email.toLowerCase()) {
const error = {
type: "is-warning" as errorType,
message: this.$t(
"Emails usually don't contain capitals, make sure you haven't made a typo."
) as string,
};
this.emailErrors = [error];
this.$forceUpdate();
}
}
maxErrorType(errors: errorMessage[]): errorType | undefined {
if (!errors || errors.length === 0) return undefined;
return errors.reduce<errorType>((acc, error) => {
if (error.type === "is-danger" || acc === "is-danger") return "is-danger";
return "is-warning";
}, "is-warning");
}
get errorEmailType(): errorType | undefined {
return this.maxErrorType(this.emailErrors);
}
get errorPasswordType(): errorType | undefined {
return this.maxErrorType(this.passwordErrors);
}
get errorEmailMessages(): string[] {
return this.emailErrors.map(({ message }) => message);
}
get errorPasswordMessages(): string[] {
return this.passwordErrors?.map(({ message }) => message);
}
}
</script>
@@ -302,4 +353,7 @@ p.create-account {
margin: 1rem auto 2rem;
}
}
::v-deep .help.is-warning {
color: #755033;
}
</style>