From c58c9e5f9792eafa543558aac2cd6ac70a4b8a2a Mon Sep 17 00:00:00 2001
From: Thomas Citharel <tcit@tcit.fr>
Date: Mon, 7 Oct 2019 13:47:46 +0200
Subject: [PATCH] Automatically login after registration

Closes #186

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
---
 js/src/components/NavBar.vue       |  4 +++
 js/src/graphql/user.ts             |  7 ++++-
 js/src/types/current-user.model.ts |  2 ++
 js/src/views/Account/Register.vue  | 10 ++++---
 js/src/views/Home.vue              |  1 +
 js/src/views/User/Register.vue     |  4 +--
 js/src/views/User/Validate.vue     | 45 ++++++++++++++++++------------
 js/tests/e2e/specs/register.js     |  3 ++
 tsconfig.json                      |  3 ++
 9 files changed, 54 insertions(+), 25 deletions(-)
 create mode 100644 tsconfig.json

diff --git a/js/src/components/NavBar.vue b/js/src/components/NavBar.vue
index e3dee29bd..7b77a5fce 100644
--- a/js/src/components/NavBar.vue
+++ b/js/src/components/NavBar.vue
@@ -94,6 +94,9 @@ import { RouteName } from '@/router';
     identities: {
       query: IDENTITIES,
       update: ({ identities }) => identities ? identities.map(identity => new Person(identity)) : [],
+      skip() {
+        return this.currentUser.isLoggedIn === false;
+      },
     },
     config: {
       query: CONFIG,
@@ -114,6 +117,7 @@ export default class NavBar extends Vue {
 
   @Watch('currentActor')
   async initializeListOfIdentities() {
+    if (!this.currentUser.isLoggedIn) return;
     const { data } = await this.$apollo.query<{ identities: IPerson[] }>({
       query: IDENTITIES,
     });
diff --git a/js/src/graphql/user.ts b/js/src/graphql/user.ts
index c67fc5bbc..ae7ee2629 100644
--- a/js/src/graphql/user.ts
+++ b/js/src/graphql/user.ts
@@ -18,7 +18,12 @@ mutation ValidateUser($token: String!) {
       id,
       email,
       defaultActor {
-        id
+        id,
+        preferredUsername,
+        name,
+        avatar {
+            url
+        }
       }
     }
   }
diff --git a/js/src/types/current-user.model.ts b/js/src/types/current-user.model.ts
index f64387835..8633754a7 100644
--- a/js/src/types/current-user.model.ts
+++ b/js/src/types/current-user.model.ts
@@ -1,4 +1,5 @@
 import { IEvent, IParticipant } from '@/types/event.model';
+import { IPerson } from '@/types/actor/person.model';
 
 export enum ICurrentUserRole {
   USER = 'USER',
@@ -12,5 +13,6 @@ export interface ICurrentUser {
   isLoggedIn: boolean;
   role: ICurrentUserRole;
   participations: IParticipant[];
+  defaultActor: IPerson;
   drafts: IEvent[];
 }
diff --git a/js/src/views/Account/Register.vue b/js/src/views/Account/Register.vue
index 1212f572b..d0144e041 100644
--- a/js/src/views/Account/Register.vue
+++ b/js/src/views/Account/Register.vue
@@ -103,11 +103,13 @@ export default class Register extends Vue {
         mutation: REGISTER_PERSON,
         variables: Object.assign({ email: this.email }, this.person),
         update: (store, { data }) => {
-          const identitiesData = store.readQuery<{ identities: IPerson[] }>({ query: IDENTITIES });
+          if (this.userAlreadyActivated) {
+            const identitiesData = store.readQuery<{ identities: IPerson[] }>({ query: IDENTITIES });
 
-          if (identitiesData && data) {
-            identitiesData.identities.push(data.registerPerson);
-            store.writeQuery({ query: IDENTITIES, data: identitiesData });
+            if (identitiesData && data) {
+              identitiesData.identities.push(data.registerPerson);
+              store.writeQuery({ query: IDENTITIES, data: identitiesData });
+            }
           }
         },
       });
diff --git a/js/src/views/Home.vue b/js/src/views/Home.vue
index cfc033194..7d9df77a0 100644
--- a/js/src/views/Home.vue
+++ b/js/src/views/Home.vue
@@ -157,6 +157,7 @@ export default class Home extends Vue {
     const lastWeek = new Date();
     lastWeek.setDate(new Date().getDate() - 7);
 
+    if (this.currentUser.isLoggedIn === false) return;
     const { data } = await this.$apollo.query({
       query: LOGGED_USER_PARTICIPATIONS,
       variables: {
diff --git a/js/src/views/User/Register.vue b/js/src/views/User/Register.vue
index 2e18654c4..3cbf2945a 100644
--- a/js/src/views/User/Register.vue
+++ b/js/src/views/User/Register.vue
@@ -36,7 +36,7 @@
           </div>
         </div>
         <div class="column">
-          <form @submit="submit">
+          <form v-on:submit.prevent="submit()">
             <b-field
               :label="$t('Email')"
               :type="errors.email ? 'is-danger' : null"
@@ -69,7 +69,7 @@
 
             <b-field grouped>
               <div class="control">
-                <button type="button" class="button is-primary" @click="submit()">
+                <button class="button is-primary">
                   {{ $t('Register') }}
                 </button>
               </div>
diff --git a/js/src/views/User/Validate.vue b/js/src/views/User/Validate.vue
index 6cde21a3b..4ef5079d5 100644
--- a/js/src/views/User/Validate.vue
+++ b/js/src/views/User/Validate.vue
@@ -17,11 +17,13 @@
 </template>
 
 <script lang="ts">
-import { VALIDATE_USER } from '@/graphql/user';
+import { VALIDATE_USER, UPDATE_CURRENT_USER_CLIENT } from '@/graphql/user';
 import { Component, Prop, Vue } from 'vue-property-decorator';
 import { AUTH_USER_ID } from '@/constants';
 import { RouteName } from '@/router';
-import { saveTokenData } from '@/utils/auth';
+import { saveUserData, changeIdentity } from '@/utils/auth';
+import { ILogin } from '@/types/login.model';
+import { ICurrentUserRole } from '@/types/current-user.model';
 
 @Component
 export default class Validate extends Vue {
@@ -36,24 +38,37 @@ export default class Validate extends Vue {
 
   async validateAction() {
     try {
-      const { data } = await this.$apollo.mutate({
+      const { data } = await this.$apollo.mutate<{ validateUser: ILogin }>({
         mutation: VALIDATE_USER,
         variables: {
           token: this.token,
         },
       });
 
-      this.saveUserData(data);
+      if (data) {
+        saveUserData(data.validateUser);
 
-      const user = data.validateUser.user;
-      console.log(user);
-      if (user.defaultActor) {
-        await this.$router.push({ name: RouteName.HOME });
-      } else { // If the user didn't register any profile yet, let's create one for them
-        await this.$router.push({
-          name: RouteName.REGISTER_PROFILE,
-          params: { email: user.email, userAlreadyActivated: 'true' },
+        const user = data.validateUser.user;
+
+        await this.$apollo.mutate({
+          mutation: UPDATE_CURRENT_USER_CLIENT,
+          variables: {
+            id: user.id,
+            email: user.email,
+            isLoggedIn: true,
+            role: ICurrentUserRole.USER,
+          },
         });
+
+        if (user.defaultActor) {
+          await changeIdentity(this.$apollo.provider.defaultClient, user.defaultActor);
+          await this.$router.push({ name: RouteName.HOME });
+        } else { // If the user didn't register any profile yet, let's create one for them
+          await this.$router.push({
+            name: RouteName.REGISTER_PROFILE,
+            params: { email: user.email, userAlreadyActivated: 'true' },
+          });
+        }
       }
     } catch (err) {
       console.error(err);
@@ -62,11 +77,5 @@ export default class Validate extends Vue {
       this.loading = false;
     }
   }
-
-  saveUserData({ validateUser: login }) {
-    localStorage.setItem(AUTH_USER_ID, login.user.id);
-
-    saveTokenData(login);
-  }
 }
 </script>
diff --git a/js/tests/e2e/specs/register.js b/js/tests/e2e/specs/register.js
index 84bedda28..2553f51bc 100644
--- a/js/tests/e2e/specs/register.js
+++ b/js/tests/e2e/specs/register.js
@@ -65,5 +65,8 @@ describe('Registration', () => {
     cy.location().should((loc) => {
       expect(loc.pathname).to.eq('/');
     });
+
+    cy.contains('.navbar-link', 'tester');
+    cy.contains('article.message.is-info', 'Welcome back tester account');
   });
 });
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 000000000..ac08cb255
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,3 @@
+{
+    "extends": "./js/tsconfig.json"
+}
\ No newline at end of file