Page MenuHomePhorge

No OneTemporary

Authored By
Unknown
Size
13 KB
Referenced Files
None
Subscribers
None
diff --git a/src/app/Http/Controllers/API/SignupController.php b/src/app/Http/Controllers/API/SignupController.php
index b6e31296..41ccaf38 100644
--- a/src/app/Http/Controllers/API/SignupController.php
+++ b/src/app/Http/Controllers/API/SignupController.php
@@ -1,168 +1,168 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\SignupCode;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
class SignupController extends Controller
{
/**
* Starts signup process.
*
* Verifies user name and email/phone, sends verification email/sms message.
* Returns the verification code.
*
* @param Illuminate\Http\Request HTTP request
*
* @return \Illuminate\Http\JsonResponse JSON response
*/
public function init(Request $request)
{
// Validate user name and email
// TODO: Extended validation and support for phone number
$v = Validator::make(
$request->all(),
[
'email' => 'required|email',
'name' => 'required',
]
);
if ($v->fails()) {
return response()->json(['status' => 'error', 'errors' => $v->errors()], 422);
}
// Generate the verification code
$code = SignupCode::create([
'data' => [
'email' => $request->email,
'name' => $request->name,
]
]);
// TODO: send email/sms message
return response()->json(['status' => 'success', 'code' => $code->code]);
}
/**
* Validation of the verification code.
*
* @param Illuminate\Http\Request HTTP request
*
* @return \Illuminate\Http\JsonResponse JSON response
*/
public function verify(Request $request)
{
// Validate the request args
$v = Validator::make(
$request->all(),
[
'code' => 'required',
'short_code' => 'required',
]
);
if ($v->fails()) {
return response()->json(['status' => 'error', 'errors' => $v->errors()], 422);
}
// Validate the code
$code = SignupCode::find($request->code);
if (empty($code)
|| $code->isExpired()
|| Str::upper($request->short_code) !== Str::upper($code->short_code)
) {
$errors = ['short_code' => "The code is invalid or expired."];
return response()->json(['status' => 'error', 'errors' => $errors], 422);
}
// Return user name and email/phone from the codes database on success
return response()->json([
'status' => 'success',
'email' => $code->data['email'],
'name' => $code->data['name'],
]);
}
/**
* Finishes the signup process by creating the user account.
*
* @param Illuminate\Http\Request HTTP request
*
* @return \Illuminate\Http\JsonResponse JSON response
*/
public function signup(Request $request)
{
// Validate input
$v = Validator::make(
$request->all(),
[
'domain' => 'required|min:3',
'login' => 'required|min:2',
'password' => 'required|min:3|confirmed',
]
);
if ($v->fails()) {
return response()->json(['status' => 'error', 'errors' => $v->errors()], 422);
}
$login = $request->login . '@' . $request->domain;
// TODO: check if specified domain is ours
// TODO: validate login
// Validate verification codes (again)
$v = $this->verify($request);
if ($v->status() !== 200) {
return $v;
}
$code_data = $v->getData();
$user_name = $code_data->name;
$user_email = $code_data->email;
// TODO: check if user with specified login already exists
$user = User::create(
[
// TODO: Save the external email (or phone) ?
'name' => $user_name,
'email' => $login,
'password' => $request->password,
]
);
- $token = auth()->login($user);
-
// Remove the verification code
SignupCode::destroy($request->code);
+ $token = auth()->login($user);
+
return $this->respondWithToken($token);
}
/**
* Get the token array structure.
*
* @param string $token Respond with this token.
*
* @return \Illuminate\Http\JsonResponse JSON response
*/
protected function respondWithToken($token)
{
return response()->json([
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => Auth::guard()->factory()->getTTL() * 60,
]);
}
}
diff --git a/src/resources/vue/components/Signup.vue b/src/resources/vue/components/Signup.vue
index 40243efc..e60d1716 100644
--- a/src/resources/vue/components/Signup.vue
+++ b/src/resources/vue/components/Signup.vue
@@ -1,166 +1,166 @@
<template>
<div class="container">
<div class="card" id="step1">
<div class="card-body">
<h4 class="card-title">Step 1/3</h4>
<p class="card-text">
Sign up to start your free month.
</p>
<form v-on:submit.prevent="submitStep1" data-validation-prefix="signup_">
<div class="form-group">
<label for="signup_name" class="sr-only">Your Name</label>
<input type="text" class="form-control" id="signup_name" placeholder="Your Name" required autofocus v-model="name">
</div>
<div class="form-group">
<label for="signup_email" class="sr-only">Existing Email or Phone Number</label>
<input type="text" class="form-control" id="signup_email" placeholder="Existing Email or Phone Number" required v-model="email">
</div>
<button class="btn btn-primary" type="submit">Continue</button>
</form>
</div>
</div>
<div class="card d-none" id="step2">
<div class="card-body">
<h4 class="card-title">Step 2/3</h4>
<p class="card-text">
We sent out a confirmation code to PHONE/EMAIL.
Enter the code we sent you, or click the link in the message.
</p>
<form v-on:submit.prevent="submitStep2" data-validation-prefix="signup_">
<div class="form-group">
<label for="signup_code" class="sr-only">Confirmation Code</label>
<input type="text" class="form-control" id="signup_code" placeholder="Confirmation Code" required v-model="short_code">
</div>
<button class="btn btn-secondary" type="button" v-on:click="stepBack">Back</button>
<button class="btn btn-primary" type="submit">Continue</button>
</form>
</div>
</div>
<div class="card d-none" id="step3">
<div class="card-body">
<h4 class="card-title">Step 3/3</h4>
<p class="card-text">
Create your Kolab identity (you can choose additional addresses later).
</p>
<form v-on:submit.prevent="submitStep3" data-validation-prefix="signup_">
<div class="form-group">
<label for="signup_login" class="sr-only"></label>
<div class="input-group">
<input type="text" class="form-control" id="signup_login" required>
<span class="input-group-text border-left-0 border-right-0 rounded-0">@</span>
<select class="custom-select rounded-right" id="signup_domain">
<option value="kolabnow.com">kolabnow.com</option>
<option value="kolabnow.com">mykolab.com</option>
</select>
</div>
</div>
<div class="form-group">
<label for="signup_password" class="sr-only">Password</label>
<input type="password" class="form-control" id="signup_password" placeholder="Password" required v-model="password">
</div>
<div class="form-group">
<label for="signup_confirm" class="sr-only">Confirm Password</label>
<input type="password" class="form-control" id="signup_confirm" placeholder="Confirm Password" required v-model="password_confirmation">
</div>
<button class="btn btn-secondary" type="button" v-on:click="stepBack">Back</button>
<button class="btn btn-primary" type="submit">Submit</button>
</form>
</div>
</div>
</div>
</template>
<script>
import store from '../js/store'
export default {
data() {
return {
email: '',
name: '',
code: '',
short_code: '',
password: '',
password_confirmation: ''
}
},
created() {
// Verification code provided, jump to Step 2
if (this.$route.params.code && /^([A-Z0-9]+)-([a-zA-Z0-9]+)$/.test(this.$route.params.code)) {
this.short_code = RegExp.$1
this.code = RegExp.$2
this.submitStep2()
}
},
methods: {
// Submits data to the API, validates and gets verification code
submitStep1() {
this.$root.$emit('clearFormValidation', $('#step1 form'))
axios.post('/api/auth/signup/init', {
email: this.email,
name: this.name
}).then(response => {
$('#step1').addClass('d-none')
$('#step2').removeClass('d-none').find('input').first().focus()
this.code = response.data.code
})
},
// Submits the code to the API for verification
submitStep2() {
this.$root.$emit('clearFormValidation', $('#step2 form'))
axios.post('/api/auth/signup/verify', {
email: this.email,
name: this.name,
code: this.code,
short_code: this.short_code
}).then(response => {
$('#step1,#step2').addClass('d-none')
$('#step3').removeClass('d-none').find('input').first().focus()
$('#signup_domain > option').first().prop('selected', true)
// Reset user name/email, we don't have them if user used a verification link
this.name = response.data.name
this.email = response.data.email
})
},
// Submits the data to the API to create the user account
submitStep3() {
this.$root.$emit('clearFormValidation', $('#step3 form'))
axios.post('/api/auth/signup', {
code: this.code,
short_code: this.short_code,
email: this.email,
// FIXME: For some reason if I use v-model for login and domain fields
// whenever user enters something in login input the domain field
// is reset to an empty value. We'll use jQuery for now
login: $('#signup_login').val(),
domain: $('#signup_domain').val(),
password: this.password,
password_confirmation: this.password_confirmation
}).then(response => {
$('#step2').addClass('d-none')
$('#step3').removeClass('d-none').find('input').first().focus()
- // login user, store the token and redirect to dashboard
+ // auto-login and goto dashboard
store.commit('loginUser')
localStorage.setItem('token', response.data.access_token)
this.$router.push({name: 'dashboard'})
})
},
// Moves the user a step back in registration form
stepBack(e) {
var card = $(e.target).closest('.card')
card.prev().removeClass('d-none')
card.addClass('d-none').find('form')[0].reset()
}
}
}
</script>
diff --git a/src/resources/vue/js/store/index.js b/src/resources/vue/js/store.js
similarity index 100%
rename from src/resources/vue/js/store/index.js
rename to src/resources/vue/js/store.js

File Metadata

Mime Type
text/x-diff
Expires
Fri, Apr 24, 11:05 AM (1 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18841818
Default Alt Text
(13 KB)

Event Timeline