Skip to content

Commit

Permalink
signup page checks and also:
Browse files Browse the repository at this point in the history
move to markdown-it #196
signup page checks #206
forum link new tab #207
add hosting status to signup page
  • Loading branch information
lucaslcode committed Aug 19, 2020
1 parent 57e22ad commit 02fd966
Show file tree
Hide file tree
Showing 17 changed files with 166 additions and 65 deletions.
2 changes: 2 additions & 0 deletions app/backend/src/couchers/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
HOST_REQUEST_IN_PAST = "This host request is in the past."
HOST_REQUEST_NOT_FOUND = "Couldn't find that host request."
HOST_REQUEST_SENT_OR_RECEIVED = "Can't only list sent and also only received requests."
HOSTING_STATUS_REQUIRED = "Hosting status is required."
INVALID_BIRTHDATE = "Invalid birthdate."
INVALID_COLOR = "Invalid color."
INVALID_DATE = "Invalid date."
INVALID_EMAIL = "Invalid email."
Expand Down
13 changes: 11 additions & 2 deletions app/backend/src/couchers/servicers/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from couchers.interceptors import AuthValidatorInterceptor
from couchers.models import LoginToken, SignupToken, User, UserSession
from couchers.tasks import send_login_email, send_signup_email
from couchers.servicers.api import hostingstatus2sql
from couchers import errors
from pb import auth_pb2, auth_pb2_grpc
from sqlalchemy import func
Expand Down Expand Up @@ -160,7 +161,10 @@ def CompleteSignup(self, request, context):
context.abort(grpc.StatusCode.NOT_FOUND, errors.INVALID_TOKEN)

# should be in YYYY/MM/DD format, will raise exception if can't parse
birthdate = datetime.fromisoformat(request.birthdate)
try:
birthdate = datetime.fromisoformat(request.birthdate)
except:
context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.INVALID_BIRTHDATE)

# check email again
if not is_valid_email(signup_token.email):
Expand All @@ -175,13 +179,18 @@ def CompleteSignup(self, request, context):
context.abort(grpc.StatusCode.INVALID_ARGUMENT,
errors.INVALID_NAME)

if not request.hosting_status:
context.abort(grpc.StatusCode.INVALID_ARGUMENT,
errors.HOSTING_STATUS_REQUIRED)

user = User(
email=signup_token.email,
username=request.username,
name=request.name,
city=request.city,
gender=request.gender,
birthdate=birthdate
birthdate=birthdate,
hosting_status=hostingstatus2sql[request.hosting_status]
)

# happens in same transaction
Expand Down
5 changes: 3 additions & 2 deletions app/backend/src/tests/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from couchers.models import Base, SignupToken, LoginToken, User
from couchers.servicers.auth import Auth
from pb import auth_pb2, auth_pb2_grpc
from pb import auth_pb2, auth_pb2_grpc, api_pb2

from tests.test_fixtures import db

Expand Down Expand Up @@ -58,7 +58,8 @@ def test_basic_signup(db):
name="Räksmörgås",
city="Minas Tirith",
birthdate="1980-12-31",
gender="Robot"))
gender="Robot",
hosting_status=api_pb2.HOSTING_STATUS_CAN_HOST))
assert isinstance(reply.token, str)


Expand Down
3 changes: 2 additions & 1 deletion app/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,20 @@
"core-js": "^3.6.5",
"google-protobuf": "^3.12.2",
"grpc-web": "^1.1.0",
"markdown-it": "^10.0.0",
"moment": "^2.26.0",
"prettier": "^2.0.5",
"vue": "^2.6.11",
"vue-class-component": "^7.2.3",
"vue-property-decorator": "^8.4.2",
"vue-router": "^3.2.0",
"vue-simple-markdown": "^1.1.4",
"vuetify": "^2.2.11",
"vuex": "^3.4.0",
"vuex-persistedstate": "^3.0.1"
},
"devDependencies": {
"@types/google-protobuf": "^3.7.2",
"@types/markdown-it": "^10.0.2",
"@typescript-eslint/eslint-plugin": "^2.33.0",
"@typescript-eslint/parser": "^2.33.0",
"@vue/cli-plugin-babel": "~4.4.0",
Expand Down
7 changes: 6 additions & 1 deletion app/frontend/src/components/Drawer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,12 @@
<v-list-item-title>Friends</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-list-item link href="https://community.couchers.org">
<v-list-item
link
href="https://community.couchers.org"
target="_blank"
rel="noopener noreferrer"
>
<v-list-item-icon>
<v-icon>mdi-account-group</v-icon>
</v-list-item-icon>
Expand Down
4 changes: 0 additions & 4 deletions app/frontend/src/components/EditableDropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@

<script lang="ts">
import Vue from "vue"
import VueSimpleMarkdown from "vue-simple-markdown"
import "vue-simple-markdown/dist/vue-simple-markdown.css"
Vue.use(VueSimpleMarkdown)
export default Vue.extend({
props: {
Expand Down
2 changes: 1 addition & 1 deletion app/frontend/src/components/EditableTextarea.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<script lang="ts">
import Vue from "vue"
import Markdown from "@/components/Markdown.vue"
import Markdown from "../components/Markdown.vue"
export default Vue.extend({
props: {
Expand Down
13 changes: 9 additions & 4 deletions app/frontend/src/components/Markdown.vue
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
<template>
<vue-simple-markdown :source="source" :image="false"></vue-simple-markdown>
<v-container v-html="rendered"></v-container>
</template>

<script lang="ts">
import Vue from "vue"
import VueSimpleMarkdown from "vue-simple-markdown"
import "vue-simple-markdown/dist/vue-simple-markdown.css"
import markdown from "markdown-it"
Vue.use(VueSimpleMarkdown)
const md = new markdown().disable("image")
export default Vue.extend({
props: {
source: {
type: String,
},
},
computed: {
rendered() {
return md.render(this.source)
},
},
})
</script>
4 changes: 2 additions & 2 deletions app/frontend/src/components/ReportDialogButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@

<script lang="ts">
import Vue from "vue"
import { ReportReq } from "@/pb/api_pb"
import { ReportReq } from "../pb/api_pb"
import ErrorAlert from "./ErrorAlert.vue"
import { client } from "@/api"
import { client } from "../api"
export default Vue.extend({
props: {
Expand Down
2 changes: 1 addition & 1 deletion app/frontend/src/components/RequestHostDialogButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@

<script lang="ts">
import Vue, { PropType } from "vue"
import { User } from "@/pb/api_pb"
import { User } from "../pb/api_pb"
import ErrorAlert from "./ErrorAlert.vue"
import { requestsClient } from "../api"
Expand Down
2 changes: 1 addition & 1 deletion app/frontend/src/components/SendMessageDialogButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

<script lang="ts">
import Vue, { PropType } from "vue"
import { User } from "@/pb/api_pb"
import { User } from "../pb/api_pb"
import ErrorAlert from "./ErrorAlert.vue"
import { conversations } from "../api"
Expand Down
2 changes: 0 additions & 2 deletions app/frontend/src/shims-vue.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,3 @@ declare module "*.vue" {
import Vue from "vue"
export default Vue
}

declare module "vue-simple-markdown"
68 changes: 67 additions & 1 deletion app/frontend/src/views/CompleteSignup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@
></v-date-picker>
</v-menu>
</v-row>
<v-row class="mt-3">
<v-select
v-model="hostingStatus"
:items="hostingStatusItems"
label="Can you host?"
></v-select>
</v-row>
<v-row class="mt-5"
><v-btn
v-on:click="submit"
Expand Down Expand Up @@ -125,12 +132,14 @@ import Store from "../store"
import Router from "../router"
import ErrorAlert from "../components/ErrorAlert.vue"
import { displayHostingStatus } from "../utils"
import { HostingStatus } from "../pb/api_pb"
export default Vue.extend({
data: () => ({
genders: ["Male", "Female", "Genderqueer/nonbinary"],
loading: false,
error: null as null | Error,
error: null as null | Error | Array<Error>,
successMessages: [] as Array<string>,
username: "",
usernameErrorMessages: [] as Array<string>,
Expand All @@ -143,6 +152,7 @@ export default Vue.extend({
date: "",
dateMenu: false,
gender: "",
hostingStatus: HostingStatus.HOSTING_STATUS_UNSPECIFIED,
rules: {
required: (value: string) => !!value || "Required.",
},
Expand All @@ -156,6 +166,17 @@ export default Vue.extend({
this.fetchData()
},
computed: {
hostingStatusItems() {
return [
{ text: "Can host", value: HostingStatus.HOSTING_STATUS_CAN_HOST },
{ text: "Maybe", value: HostingStatus.HOSTING_STATUS_MAYBE },
{ text: "Difficult", value: HostingStatus.HOSTING_STATUS_DIFFICULT },
{ text: "Can't host", value: HostingStatus.HOSTING_STATUS_CANT_HOST },
]
},
},
methods: {
fetchData() {
this.emailLoading = false
Expand Down Expand Up @@ -188,6 +209,22 @@ export default Vue.extend({
this.usernameErrorMessages = []
this.usernameSuccessMessages = []
if (this.username == "") return
if (this.username.search(/[A-Z]/) != -1) {
this.usernameErrorMessages.push("Only use lowercase letters.")
}
if (this.username.search(/^\d/) != -1) {
this.usernameErrorMessages.push("Don't start with a number.")
}
if (this.username.search(/[^a-z0-9]/) != -1) {
this.usernameErrorMessages.push("Only use basic letters and numbers.")
}
if (this.usernameErrorMessages.length > 0) return
const req = new UsernameValidReq()
req.setUsername(this.username)
Expand All @@ -208,6 +245,32 @@ export default Vue.extend({
},
submit() {
this.error = []
if (this.usernameErrorMessages.length > 0) {
this.error.push(Error("Please fix your username."))
}
if (
this.name == "" ||
this.city == "" ||
this.date == "" ||
this.username == "" ||
!this.hostingStatus
) {
this.error.push(Error("All fields are required (except gender)."))
}
if (this.date.search(/^\d\d\d\d-\d\d-\d\d$/) == -1) {
this.error.push(Error("Birthdate must be in the format YYYY-MM-DD"))
}
if (this.error.length > 0) {
return
} else {
this.error = null
}
this.loading = true
this.clearMessages()
Expand All @@ -219,6 +282,7 @@ export default Vue.extend({
req.setCity(this.city)
req.setBirthdate(this.date)
req.setGender(this.gender)
req.setHostingStatus(this.hostingStatus)
authClient
.completeSignup(req)
Expand All @@ -233,6 +297,8 @@ export default Vue.extend({
this.error = err
})
},
displayHostingStatus,
},
})
</script>
2 changes: 1 addition & 1 deletion app/frontend/src/views/HostRequests.vue
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ import {
} from "../pb/requests_pb"
import { client, requestsClient } from "../api"
import { mapState } from "vuex"
import { HostRequest } from "@/pb/requests_pb"
import { HostRequest } from "../pb/requests_pb"
import ErrorAlert from "../components/ErrorAlert.vue"
import { Timestamp } from "google-protobuf/google/protobuf/timestamp_pb"
Expand Down
20 changes: 10 additions & 10 deletions app/frontend/src/views/Profile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -313,18 +313,18 @@ export default Vue.extend({
error: null as Error | null,
HostingStatus,
hostingStatusChoices: [
{ text: "(Leave blank)", value: 1 },
{ text: "Can host", value: 2 },
{ text: "Maybe", value: 3 },
{ text: "Difficult", value: 4 },
{ text: "Can't host", value: 5 },
{ text: "", value: HostingStatus.HOSTING_STATUS_UNKNOWN },
{ text: "Can host", value: HostingStatus.HOSTING_STATUS_CAN_HOST },
{ text: "Maybe", value: HostingStatus.HOSTING_STATUS_MAYBE },
{ text: "Difficult", value: HostingStatus.HOSTING_STATUS_DIFFICULT },
{ text: "Can't host", value: HostingStatus.HOSTING_STATUS_CANT_HOST },
],
smokingAllowedChoices: [
{ text: "", value: 1 },
{ text: "Yes", value: 2 },
{ text: "Window", value: 3 },
{ text: "Outside", value: 4 },
{ text: "No", value: 5 },
{ text: "", value: SmokingLocation.SMOKING_LOCATION_UNKNOWN },
{ text: "Yes", value: SmokingLocation.SMOKING_LOCATION_YES },
{ text: "Window", value: SmokingLocation.SMOKING_LOCATION_WINDOW },
{ text: "Outside", value: SmokingLocation.SMOKING_LOCATION_OUTSIDE },
{ text: "No", value: SmokingLocation.SMOKING_LOCATION_NO },
],
boolChoices: [
{ text: "", value: null },
Expand Down
Loading

0 comments on commit 02fd966

Please sign in to comment.