added feature for OTP-SMS Koperasi
This commit is contained in:
committed by
nurafrinaalimi16
parent
a9bbe017d3
commit
8b54416e2b
@@ -43,3 +43,8 @@ MAIL_ENCRYPTION=null
|
|||||||
PUSHER_APP_ID=
|
PUSHER_APP_ID=
|
||||||
PUSHER_APP_KEY=
|
PUSHER_APP_KEY=
|
||||||
PUSHER_APP_SECRET=
|
PUSHER_APP_SECRET=
|
||||||
|
|
||||||
|
ONEWAY_SMS_USERNAME=APIFKZQX6MN6N
|
||||||
|
ONEWAY_SMS_PASSWORD=APIFKZQX6MN6N9YHXP
|
||||||
|
ONEWAY_SMS_SENDERID=INFO
|
||||||
|
ONEWAY_SMS_LANG=1
|
||||||
|
|||||||
@@ -5,14 +5,102 @@ namespace App\Http\Controllers\API\v1\Voter;
|
|||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Controllers\Util;
|
use App\Http\Controllers\Util;
|
||||||
|
use App\UserOTP;
|
||||||
|
use App\Voter;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Exception;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
|
||||||
class LoginController extends Controller
|
class LoginController extends Controller
|
||||||
{
|
{
|
||||||
public function __invoke(Request $request)
|
public function __invoke(Request $request)
|
||||||
{
|
{
|
||||||
//return response()->json(Auth::guard('user'));
|
//return response()->json(Auth::guard('user'));
|
||||||
if (Auth::guard('voter')->attempt(['no_kp' => $request->no_kp, 'password' => 'admin', 'election_id' => Util::getCurrentElection()])) {
|
|
||||||
|
/* Request OTP */
|
||||||
|
try{
|
||||||
|
$currentDateTime = Carbon::now();
|
||||||
|
|
||||||
|
$expired_at = Carbon::now()->addMinutes(config('onewaysms.minutes'));
|
||||||
|
$created_at = $currentDateTime->toDateTimeString();
|
||||||
|
|
||||||
|
$voter = Voter::where('no_kp',$request->no_kp)->firstOrFail();
|
||||||
|
|
||||||
|
if($voter){
|
||||||
|
$expiration = $this->checkExpirationTAC($request->no_kp);
|
||||||
|
|
||||||
|
if($expiration['notexpired'] == true){
|
||||||
|
throw new \Exception('Expired TAC : ' . $expiration['remaining']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sms_token = $this->getTokenSMS($voter->telefon,$currentDateTime);
|
||||||
|
|
||||||
|
if($sms_token == 'error'){
|
||||||
|
throw new \Exception('error in getting the data from SMSToken');
|
||||||
|
}
|
||||||
|
|
||||||
|
$user_otp = new UserOTP();
|
||||||
|
$user_otp->nokp = $voter->no_kp;
|
||||||
|
$user_otp->telefon = $voter->telefon;
|
||||||
|
$user_otp->token = $sms_token;
|
||||||
|
$user_otp->created_at = $created_at;
|
||||||
|
$user_otp->expired_at = $expired_at;
|
||||||
|
$user_otp->save();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'status' => 'success',
|
||||||
|
'message' => 'generated SMS Token',
|
||||||
|
'notel' => $voter->telefon,
|
||||||
|
'nokp' => $voter->no_kp,
|
||||||
|
|
||||||
|
]);
|
||||||
|
|
||||||
|
}else{
|
||||||
|
return response()->json([
|
||||||
|
'status' => 'failed',
|
||||||
|
'message' => 'Does not found NO KP.'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}catch(Exception $e){
|
||||||
|
return response()->json([
|
||||||
|
'status' => 'failed',
|
||||||
|
'message' => 'Error: ' . $e->getMessage()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function checkExpirationTAC($nokp) : Array{
|
||||||
|
$currentDateTime = Carbon::now();
|
||||||
|
|
||||||
|
$expiretac = UserOTP::where('nokp',$nokp)
|
||||||
|
->whereDate('created_at','=',$currentDateTime)
|
||||||
|
->whereDate('expired_at','=',$currentDateTime)
|
||||||
|
->whereTime('expired_at','>=',$currentDateTime->toTimeString())
|
||||||
|
->whereTime('created_at','<=',$currentDateTime->toTimeString())
|
||||||
|
->latest()
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if($expiretac){
|
||||||
|
$remaining = $this->getRemainingTime($expiretac->expired_at);
|
||||||
|
return ['notexpired' => true,'remaining' => $remaining];
|
||||||
|
}else{
|
||||||
|
return ['notexpired' => false];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function verifyTAC(Request $request){
|
||||||
|
|
||||||
|
$authenticateOTP = $this->getTACModel($request->no_kp,$request->token);
|
||||||
|
|
||||||
|
if(!$authenticateOTP['condition']){
|
||||||
|
return response()->json([
|
||||||
|
'status' => 'failed',
|
||||||
|
'message' => $authenticateOTP['message']
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Auth::guard('voter')->attempt(['no_kp' => $request->no_kp, 'password' => 'admin', 'election_id' => Util::getCurrentElection()])) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'status' => 'success',
|
'status' => 'success',
|
||||||
'message' => 'Login successfully.',
|
'message' => 'Login successfully.',
|
||||||
@@ -26,5 +114,99 @@ class LoginController extends Controller
|
|||||||
'message' => 'Invalid ID.'
|
'message' => 'Invalid ID.'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'status' => 'success',
|
||||||
|
'message' => 'Login successfully.',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getTACModel($no_kp,$token){
|
||||||
|
$currentDateTime = Carbon::now();
|
||||||
|
|
||||||
|
$result = UserOTP::where('nokp',$no_kp)
|
||||||
|
->whereDate('created_at','=',$currentDateTime)
|
||||||
|
->whereDate('expired_at','=',$currentDateTime)
|
||||||
|
->whereTime('expired_at','>=',$currentDateTime->toTimeString())
|
||||||
|
->whereTime('created_at','<=',$currentDateTime->toTimeString())
|
||||||
|
->latest()
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if(!$result){
|
||||||
|
return ['condition' => false, 'message' => 'Token Expired'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if($result['token'] == $token){
|
||||||
|
return ['condition' => true];
|
||||||
|
}else{
|
||||||
|
return ['condition' => false, 'message' => 'Invalid Token'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getTokenSMS($tele,$date){
|
||||||
|
$tac_token = $this->randum_number(6,2,false);
|
||||||
|
if(env("APP_ENV") == 'production'){
|
||||||
|
$mobileno = '6' . $tele;
|
||||||
|
$messages = sprintf(config('onewaysms.message'),$tac_token,$date);
|
||||||
|
|
||||||
|
var_dump($mobileno,$messages);
|
||||||
|
$parameter = [
|
||||||
|
'apiusername' => env("ONEWAY_SMS_USERNAME"),
|
||||||
|
'apipassword' => env("ONEWAY_SMS_PASSWORD"),
|
||||||
|
'senderid' => env("ONEWAY_SMS_SENDERID",'INFO'),
|
||||||
|
'mobileno' => $mobileno,
|
||||||
|
'message'=> $messages,
|
||||||
|
'languagetype'=> env("ONEWAY_SMS_LANG",1)
|
||||||
|
];
|
||||||
|
|
||||||
|
$client = new Client(['verify' => false]);
|
||||||
|
$status = $client->get('http://gateway.onewaysms.com.my:10001/api.aspx',[
|
||||||
|
'query' => $parameter
|
||||||
|
]);
|
||||||
|
|
||||||
|
if($status){
|
||||||
|
return $tac_token;
|
||||||
|
}else{
|
||||||
|
return 'error';
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
return $tac_token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function randum_number($len = 6,$dup = 1, $sort = false){
|
||||||
|
if($dup < 1)
|
||||||
|
throw new \InvalidArgumentException('Second argument is < 1');
|
||||||
|
|
||||||
|
$num = range(0,9);
|
||||||
|
shuffle($num);
|
||||||
|
|
||||||
|
$num = array_slice($num, 0, ($len-$dup) + 1);
|
||||||
|
|
||||||
|
if($dup > 0){
|
||||||
|
$k = array_rand($num, 1);
|
||||||
|
for($i=0;$i<($dup-1);$i++)
|
||||||
|
{
|
||||||
|
$num[] = $num[$k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($sort){
|
||||||
|
sort($num);
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode('',$num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getRemainingTime($expired_at){
|
||||||
|
$currentDateTime = Carbon::now();
|
||||||
|
$expiredAt = Carbon::parse($expired_at);
|
||||||
|
|
||||||
|
$remainingSeconds = $currentDateTime->diffInSeconds($expiredAt);
|
||||||
|
|
||||||
|
$remainingFormatted = gmdate('H:i:s', $remainingSeconds);
|
||||||
|
|
||||||
|
return $remainingFormatted;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class UserOTP extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'user_login_otp';
|
||||||
|
protected $fillable = ['id', 'nokp','telefon', 'token', 'created_at','expired_at'];
|
||||||
|
|
||||||
|
public $timestamps = false;
|
||||||
|
}
|
||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
"php": ">=5.6.4",
|
"php": ">=5.6.4",
|
||||||
"cloudinary/cloudinary_php": "^2.3",
|
"cloudinary/cloudinary_php": "^2.3",
|
||||||
"doctrine/dbal": "^2.5",
|
"doctrine/dbal": "^2.5",
|
||||||
"guzzlehttp/guzzle": "^6.3",
|
"guzzlehttp/guzzle": "^6.5",
|
||||||
"laravel/framework": "5.8.*",
|
"laravel/framework": "5.8.*",
|
||||||
"laravel/passport": "^4.0",
|
"laravel/passport": "^4.0",
|
||||||
"laravel/tinker": "~1.0",
|
"laravel/tinker": "~1.0",
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'message' => 'KOPERASI : TAC: %s - %s NOMBOR TAC',
|
||||||
|
'minutes' => 5
|
||||||
|
];
|
||||||
|
|
||||||
|
?>
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class UserLoginOtp extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
if (!Schema::hasTable('user_login_otp'))
|
||||||
|
Schema::create('user_login_otp', function (Blueprint $table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->string('nokp', 20);
|
||||||
|
$table->string('telefon');
|
||||||
|
$table->string('token');
|
||||||
|
$table->timestamp('created_at');
|
||||||
|
$table->timestamp('expired_at');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-1
@@ -16,6 +16,9 @@
|
|||||||
"sass": "^1.50.1",
|
"sass": "^1.50.1",
|
||||||
"sass-loader": "^12.1.0",
|
"sass-loader": "^12.1.0",
|
||||||
"vue-loader": "^15.9.7",
|
"vue-loader": "^15.9.7",
|
||||||
"vue-template-compiler": "^2.6.14"
|
"vue-template-compiler": "^2.7.16"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@bachdgvn/vue-otp-input": "^1.0.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+3
@@ -3,10 +3,13 @@ require('./bootstrap.js');
|
|||||||
//import VueRouter from 'vue-router';
|
//import VueRouter from 'vue-router';
|
||||||
import Util from './util.js';
|
import Util from './util.js';
|
||||||
import routes from './routesIndex.js';
|
import routes from './routesIndex.js';
|
||||||
|
import OtpInput from "@bachdgvn/vue-otp-input";
|
||||||
|
|
||||||
|
Vue.component("v-otp-input", OtpInput);
|
||||||
|
|
||||||
Vue.use(VueRouter);
|
Vue.use(VueRouter);
|
||||||
Vue.mixin(Util);
|
Vue.mixin(Util);
|
||||||
|
Vue.use(OtpInput);
|
||||||
|
|
||||||
const router = new VueRouter({
|
const router = new VueRouter({
|
||||||
mode: 'history',
|
mode: 'history',
|
||||||
|
|||||||
@@ -43,29 +43,19 @@ export default{
|
|||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
login: function () {
|
login: function(){
|
||||||
if (this.loading) return;
|
|
||||||
|
|
||||||
let vm = this;
|
|
||||||
|
|
||||||
this.startLoading();
|
|
||||||
|
|
||||||
axios.post(config.API+'voter/login', $('#login_form').serialize())
|
axios.post(config.API+'voter/login', $('#login_form').serialize())
|
||||||
.then(response => {
|
.then(response => {
|
||||||
vm.stopLoading();
|
this.stopLoading();
|
||||||
if (this.util.showResult(response, 'success')) {
|
if (this.util.showResult(response, 'success')) {
|
||||||
localStorage['Access Token'] = `Bearer ${response.data.token}`;
|
this.$router.push({ name: 'Voter Verify',params: {'nokp' : response.data.nokp,'notel' : response.data.notel} })
|
||||||
this.util.setAuthorization();
|
}
|
||||||
vm.$router.push({name: 'Voter Home'});
|
})
|
||||||
}
|
.catch(error => {
|
||||||
})
|
vm.stopLoading();
|
||||||
.catch(error => {
|
this.util.showResult(error, 'error');
|
||||||
vm.stopLoading();
|
})
|
||||||
this.util.showResult(error, 'error');
|
|
||||||
})
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
startLoading: function () {
|
startLoading: function () {
|
||||||
this.util.notify('Logging in', 'loading');
|
this.util.notify('Logging in', 'loading');
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
|||||||
@@ -0,0 +1,154 @@
|
|||||||
|
<template>
|
||||||
|
<div class="col-md-5 col-md-offset-3">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<a @click="$router.go(-1)">Kembali</a>
|
||||||
|
<h4 class="text-center">Kod Verifikasi!</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel-body">
|
||||||
|
<form @submit.prevent="login" id="login_form">
|
||||||
|
<div class="m-4">
|
||||||
|
<span>sila masukkan kod pengesahan yang dihantar ke</span>
|
||||||
|
<br>-<b>+6 {{ $route.params.notel }}</b>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="justify-content-center d-flex" style="margin-top:20px;margin-bottom:20px;display: flex;flex-direction: row;justify-content: center;align-items: center;">
|
||||||
|
<v-otp-input
|
||||||
|
ref="otpInput"
|
||||||
|
input-classes="otp-input"
|
||||||
|
separator="-"
|
||||||
|
:num-inputs="6"
|
||||||
|
:should-auto-focus="true"
|
||||||
|
:is-input-num="true"
|
||||||
|
@on-change="handleOnChange"
|
||||||
|
@on-complete="handleOnComplete"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-bottom:20px;">
|
||||||
|
<!-- <span>dapatkan Kod baru dalam masa : 01:23 saat</span> -->
|
||||||
|
<!-- <Countdown ref="countdown"></Countdown> -->
|
||||||
|
<a @click="resendVerify">Hantar Kembali OTP!</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<input
|
||||||
|
ref="submitbtn"
|
||||||
|
type="submit"
|
||||||
|
class="btn btn-primary form-control"
|
||||||
|
value="Sahkan & Teruskan"
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import Countdown from '../../mycomponents/countdown.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components:{
|
||||||
|
Countdown
|
||||||
|
},
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
loading: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created: function(){
|
||||||
|
console.log(this.$route.params.notel);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleOnComplete(value) {
|
||||||
|
console.log("OTP completed: ", value);
|
||||||
|
this.$refs.submitbtn.disabled = false;
|
||||||
|
},
|
||||||
|
handleOnChange(value) {
|
||||||
|
console.log("OTP changed: ", value);
|
||||||
|
this.$refs.submitbtn.disabled = true;
|
||||||
|
},
|
||||||
|
handleClearInput() {
|
||||||
|
this.$refs.otpInput.clearInput();
|
||||||
|
},
|
||||||
|
resendVerify: function(){
|
||||||
|
axios.post(config.API+'voter/login', {
|
||||||
|
'no_kp' : '970403035003'
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
this.stopLoading();
|
||||||
|
if (this.util.showResult(response, 'success')) {
|
||||||
|
// this.$router.push({ name: 'Voter Verify',params: {'nokp' : response.data.nokp,'notel' : response.data.notel} })
|
||||||
|
this.$refs.countdown.restarttimer();
|
||||||
|
console.log('resend verify');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
vm.stopLoading();
|
||||||
|
this.util.showResult(error, 'error');
|
||||||
|
})
|
||||||
|
},
|
||||||
|
startLoading: function () {
|
||||||
|
this.util.notify('Logging in', 'loading');
|
||||||
|
this.loading = true;
|
||||||
|
},
|
||||||
|
stopLoading: function () {
|
||||||
|
$.notifyClose();
|
||||||
|
this.loading = false;
|
||||||
|
},
|
||||||
|
login: function () {
|
||||||
|
if (this.loading) return;
|
||||||
|
|
||||||
|
let vm = this;
|
||||||
|
|
||||||
|
this.startLoading();
|
||||||
|
console.log('OTP INPUT : ');
|
||||||
|
let otp = this.mergeOTP(this.$refs.otpInput.otp);
|
||||||
|
console.log(otp);
|
||||||
|
axios.post(config.API+'voter/verify', {
|
||||||
|
'no_kp' : this.$route.params.nokp,
|
||||||
|
'token' : otp
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
vm.stopLoading();
|
||||||
|
if (this.util.showResult(response, 'success')) {
|
||||||
|
localStorage['Access Token'] = `Bearer ${response.data.token}`;
|
||||||
|
this.util.setAuthorization();
|
||||||
|
vm.$router.push({name: 'Voter Home'});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
vm.stopLoading();
|
||||||
|
this.util.showResult(error, 'error');
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
mergeOTP: function(OTP){
|
||||||
|
return OTP.join('');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.otp-input {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
padding: 5px;
|
||||||
|
margin: 0 10px;
|
||||||
|
font-size: 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.3);
|
||||||
|
text-align: center;
|
||||||
|
&.error {
|
||||||
|
border: 1px solid red !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.otp-input::-webkit-inner-spin-button,
|
||||||
|
.otp-input::-webkit-outer-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<p>Dapatkan Kod baru dalam masa : {{ minutes }}:{{ seconds }} saat</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
minutes: 5,
|
||||||
|
seconds: 0,
|
||||||
|
timer: null // Initialize timer variable
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.startTimer(); // Start the timer when the component is created
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
startTimer() {
|
||||||
|
// Clear existing timer if it exists
|
||||||
|
if (this.timer) {
|
||||||
|
clearInterval(this.timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the timer
|
||||||
|
this.timer = setInterval(this.countdown, 1000);
|
||||||
|
},
|
||||||
|
restarttimer() {
|
||||||
|
this.startTimer();
|
||||||
|
console.log('restarted');
|
||||||
|
},
|
||||||
|
countdown() {
|
||||||
|
if (this.seconds > 0) {
|
||||||
|
this.seconds--;
|
||||||
|
} else if (this.minutes > 0) {
|
||||||
|
this.minutes--;
|
||||||
|
this.seconds = 59;
|
||||||
|
} else {
|
||||||
|
clearInterval(this.timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
clearInterval(this.timer); // Clear the timer when the component is destroyed
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
Vendored
+8
@@ -1,4 +1,6 @@
|
|||||||
import VoterLogin from './components/demo/voter/login.vue';
|
import VoterLogin from './components/demo/voter/login.vue';
|
||||||
|
import VoterVerification from './components/demo/voter/verification.vue';
|
||||||
|
|
||||||
import VoterHome from './components/demo/voter/index.vue';
|
import VoterHome from './components/demo/voter/index.vue';
|
||||||
|
|
||||||
import Home from './components/demo/voter/home/index.vue';
|
import Home from './components/demo/voter/home/index.vue';
|
||||||
@@ -91,6 +93,12 @@ export default [
|
|||||||
name: 'Voter Login'
|
name: 'Voter Login'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
path: '/verification',
|
||||||
|
component: VoterVerification,
|
||||||
|
name: 'Voter Verify'
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: '/admin/login',
|
path: '/admin/login',
|
||||||
component: AdminLogin,
|
component: AdminLogin,
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ Route::get('/user', 'Auth\UserController@index')->middleware('auth:api');
|
|||||||
Route::prefix('v1')->group(function(){ //Version 1 of my Rest API
|
Route::prefix('v1')->group(function(){ //Version 1 of my Rest API
|
||||||
//Voters API
|
//Voters API
|
||||||
Route::post('voter/login', 'API\v1\Voter\LoginController');
|
Route::post('voter/login', 'API\v1\Voter\LoginController');
|
||||||
|
Route::post('voter/verify','API\v1\Voter\LoginController@verifyTAC');
|
||||||
|
|
||||||
Route::middleware(['auth:voterAPI', 'voter'])->group(function() {
|
Route::middleware(['auth:voterAPI', 'voter'])->group(function() {
|
||||||
Route::get('election/information', 'API\v1\Election\InformationController');
|
Route::get('election/information', 'API\v1\Election\InformationController');
|
||||||
|
|||||||
Reference in New Issue
Block a user