diff --git a/requirements.txt b/requirements.txt index 95e08be..906b98f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ -setuptools~=56.0.0 +setuptools~=40.8.0 django~=2.2.13 -djangorestframework~=3.12.4 -djoser~=2.1.0 +djangorestframework~=3.9.0 \ No newline at end of file diff --git a/src/api.ts b/src/api.ts index d8a33ce..ef72ad6 100644 --- a/src/api.ts +++ b/src/api.ts @@ -2,7 +2,7 @@ import Cookies from "js-cookie"; type HTTPMethod = "GET" | "POST" | "PUT" | "PATCH"; -class APIError extends Error { +export class APIError extends Error { constructor(message: string, public readonly errors: unknown) { super(message); } @@ -29,7 +29,7 @@ async function request( } init.headers.set("Accept", "application/json"); init.headers.set("Content-Type", "application/json"); - const response = await fetch(`/api/${endpoint}/`, init); + const response = await fetch(`/${endpoint}/`, init); if (response.status !== 204) { if (response.status === successStatus) { return await response.json(); @@ -39,41 +39,69 @@ async function request( } } +async function api_request( + method: HTTPMethod, + endpoint: string, + successStatus: number, + data: any, + authToken?: string +) { + return request(method, `api/${endpoint}`, successStatus, data, authToken); +} + export class User { email: string | undefined; password: string | undefined; - private username: string | null = null; - private confidantEmail: string | null = null; + username: string | null = null; + confidantEmail: string | null = null; isAuthenticated = false; private token = ""; static async confirm(uid: string, token: string): Promise { - await request("POST", "users/activation", 204, { uid, token }); + await api_request("POST", "users/activation", 204, { uid, token }); } async login(): Promise { - const response = await request("POST", "token/login", 200, { - email: this.email, - password: this.password, - }); - this.token = response.auth_token; - this.isAuthenticated = true; + if (!this.email || !this.password) throw new APIError("", ""); + + // logout any existing sessions + //await logout() + // fetch the login endpoint we use for authentication + const loginEndpoint = "/api-auth/login/"; + // fetch the login page, so it sets csrf cookies + await window.fetch(loginEndpoint); + + // authenticate us + const body = new window.FormData(); + body.append("username", this.email); + body.append("password", this.password); + const csrf_token = Cookies.get("csrftoken"); + if (csrf_token) body.append("csrfmiddlewaretoken", csrf_token); + const res = await window.fetch(loginEndpoint, { method: "post", body }); + + // successful logins are followed by a redirect + if (res.redirected && res.status === 200) { + this.isAuthenticated = true; + } else { + throw new APIError("", ""); + } } async save(): Promise { - await request( + await api_request( "PATCH", "users/me", 200, { username: this.username, + confidant_email: this.confidantEmail, }, this.token ); } async signup(): Promise { - await request("POST", "users", 201, { + await api_request("POST", "users", 201, { email: this.email, password: this.password, }); diff --git a/src/components/UserTable.vue b/src/components/UserTable.vue index 696c59a..51e9491 100644 --- a/src/components/UserTable.vue +++ b/src/components/UserTable.vue @@ -24,11 +24,15 @@ Benutzername - + + + Vertrauensperson - + + + E-Mail-Adresse diff --git a/src/mixins.ts b/src/mixins.ts new file mode 100644 index 0000000..56575a2 --- /dev/null +++ b/src/mixins.ts @@ -0,0 +1,19 @@ +import Component from "vue-class-component"; +import Vue from "vue"; + +@Component +export class NotifyMixin extends Vue { + showError(): void { + this.$buefy.toast.open({ + message: "Es ist leider ein Fehler aufgetreten.", + type: "is-danger", + }); + } + + showSuccess(message: string): void { + this.$buefy.toast.open({ + message, + type: "is-success", + }); + } +} diff --git a/src/views/MainPage.vue b/src/views/MainPage.vue index 311ded9..7bd39ea 100644 --- a/src/views/MainPage.vue +++ b/src/views/MainPage.vue @@ -15,24 +15,34 @@