Browse Source

:art: Allow multiple tokens by email

So that you can have an email with multiple browsers or smartphone
master
Clement Desmidt 1 month ago
parent
commit
8fa74f62e8

+ 11
- 15
app/Http/Controllers/UsersController.php View File

@@ -20,24 +20,20 @@ class UsersController extends Controller
20 20
 		} catch (ValidationException $e) {
21 21
 			return response()->json(['error' => $e->errors()], 422);
22 22
 		}
23
-		
24
-		try {
25
-			$data = $this->validate($request, [
26
-				'email' => 'unique:users',
27
-			]);
28
-		} catch (ValidationException $e) {
29
-			return response()->json(['error' => $e->errors()], 409);
30
-		}
31
-		
32
-		$token = User::generateToken();
33 23
 
34
-		$user = new User(['email' => $data['email']]);
35
-		$user->api_token = $token;
36
-		$user->save();
24
+        $user = User::where('email', $data['email'])->first();
25
+        if (!$user instanceof User) {
26
+            $user = new User(['email' => $data['email']]);
27
+            $user->save();
28
+        }
29
+
30
+        $token = $user->addToken();
37 31
 
38
-		Mail::to($user->email)->send(new Confirmation($user));
32
+        if (!$user->confirmed ) {
33
+            Mail::to($user->email)->send(new Confirmation($user));
34
+        }
39 35
 
40
-		return response()->json(['status' => 'success', 'message' => 'mail sent']);
36
+		return response()->json(['status' => 'success', 'mail_sent' => !$user->confirmed, 'message' => 'mail sent', 'token' => $token->api_token]);
41 37
     }
42 38
 
43 39
     public function confirm(Request $request)

+ 10
- 0
app/Token.php View File

@@ -0,0 +1,10 @@
1
+<?php
2
+
3
+namespace App;
4
+
5
+use Illuminate\Database\Eloquent\Model;
6
+
7
+class Token extends Model
8
+{
9
+    protected $table = 'tokens';
10
+}

+ 31
- 2
app/User.php View File

@@ -15,10 +15,10 @@ class User extends Model implements Authenticatable
15 15
      */
16 16
     protected $table = 'users';
17 17
 
18
-    protected $fillable = ["email"];
18
+    protected $fillable = ['email'];
19 19
 
20 20
     public static $rules = [
21
-        "email" => "required",
21
+        'email' => 'required',
22 22
     ];
23 23
 
24 24
     /**
@@ -92,4 +92,33 @@ class User extends Model implements Authenticatable
92 92
     {
93 93
         return null;
94 94
     }
95
+
96
+    /**
97
+     * @return Token[]
98
+     */
99
+    public function getTokens()
100
+    {
101
+        return Token::where('user_id', $this->id)->all();
102
+    }
103
+
104
+    /**
105
+     * @param null|string $name
106
+     *
107
+     * @return bool|Token
108
+     */
109
+    public function addToken($name = null)
110
+    {
111
+        try {
112
+            $new_token = new Token();
113
+            $new_token->user_id = $this->id;
114
+            $new_token->api_token = self::generateToken();
115
+            $new_token->token_name = $name;
116
+
117
+            $new_token->save();
118
+
119
+            return $new_token;
120
+        } catch (\Exception $e) {
121
+            return $e->getMessage();
122
+        }
123
+    }
95 124
 }

+ 42
- 0
database/migrations/2019_04_18_210201_create_tokens.php View File

@@ -0,0 +1,42 @@
1
+<?php
2
+
3
+use Illuminate\Support\Facades\Schema;
4
+use Illuminate\Database\Schema\Blueprint;
5
+use Illuminate\Database\Migrations\Migration;
6
+
7
+class CreateTokens extends Migration
8
+{
9
+    /**
10
+     * Run the migrations.
11
+     *
12
+     * @return void
13
+     */
14
+    public function up()
15
+    {
16
+        Schema::create('tokens', static function (Blueprint $table) {
17
+            $table->increments('id');
18
+            $table->unsignedBigInteger('user_id');
19
+            $table->string('api_token')->unique();
20
+            $table->string('token_name')->nullable();
21
+            $table->foreign('user_id')->references('id')->on('users');
22
+            $table->timestamps();
23
+        });
24
+
25
+        Schema::table('users', static function (Blueprint $table) {
26
+            $table->dropColumn('api_token');
27
+        });
28
+    }
29
+
30
+    /**
31
+     * Reverse the migrations.
32
+     *
33
+     * @return void
34
+     */
35
+    public function down()
36
+    {
37
+        Schema::dropIfExists('tokens');
38
+        Schema::table('users', static function(Blueprint $table) {
39
+            $table->string('api_token')->unique();
40
+        });
41
+    }
42
+}

+ 10631
- 0
package-lock.json
File diff suppressed because it is too large
View File


+ 5
- 0
package.json View File

@@ -18,5 +18,10 @@
18 18
         "lodash": "^4.17.5",
19 19
         "popper.js": "^1.12",
20 20
         "vue": "^2.5.7"
21
+    },
22
+    "dependencies": {
23
+        "clipboard-copy": "^3.0.0",
24
+        "detect-browser": "^4.4.0",
25
+        "vue-resource": "^1.5.1"
21 26
     }
22 27
 }

+ 17
- 2
resources/js/components/App.vue View File

@@ -11,12 +11,16 @@
11 11
 			<button class="btn btn-primary btn-lg" type="submit" @click="register()">Generate</button>
12 12
 			<div v-show="success" class="alert alert-success" role="alert">{{ message }}</div>
13 13
 			<div v-show="error" class="alert alert-warning" role="alert">{{ message }}</div>
14
+			<div class="info" v-show="token !== ''" id="token_clip">{{ token }}</div>
14 15
 			<button class="btn btn-primary btn-lg" v-show="resend" type="submit" @click="resendAction()">Resend link</button>
15 16
 		</div>
16 17
     </div>
17 18
 </template>
18 19
 
19 20
 <script>
21
+	const { detect } = require('detect-browser');
22
+	const browser = detect();
23
+	const copy = require('clipboard-copy');
20 24
     export default {
21 25
         name: 'registration',
22 26
         resource: null,
@@ -28,18 +32,29 @@
28 32
                 error: false,
29 33
 				resend: false,
30 34
                 message: '',
35
+				token: ''
31 36
             }
32 37
         },
33 38
         methods: {
34 39
             register: function() {
35 40
                 this.resetMessages();
36 41
                 this.loading = true;
37
-                var formData = new FormData();
42
+                let formData = new FormData();
38 43
                 formData.append('email', this.email);
39 44
                 Vue.http.post('api/register', formData, {emulateJSON: false}).then((response) => {
45
+                	let data = response.data;
46
+                	this.token = data.token ? data.token : '';
40 47
 					this.loading = false;
41 48
                     this.success = true;
42
-                    this.message = 'An email has been sent to verify it.';
49
+                    this.message = '';
50
+                    if (data.mail_sent) {
51
+						this.message = 'An email has been sent to verify it.';
52
+					}
53
+					document.addEventListener('click',function(e){
54
+						if (e.target && e.target.id === "token_clip") {
55
+							copy(data.token);
56
+						}
57
+					});
43 58
                 }, (response) => {
44 59
                     this.loading = false;
45 60
                     this.error = true;

Loading…
Cancel
Save