Ver a proveniência

add authentification mecanism

pull/44/head
Guillaume Vincent há 8 anos
ascendente
cometimento
073dd185ac
10 ficheiros alterados com 262 adições e 100 eliminações
  1. +40
    -16
      app/app.vue
  2. +15
    -5
      app/components/auth/auth.vue
  3. +34
    -55
      app/components/auth/login.vue
  4. +42
    -1
      app/components/auth/register.vue
  5. +24
    -2
      app/components/entries.vue
  6. +3
    -1
      app/components/index.vue
  7. +15
    -10
      app/components/password-generator.vue
  8. +26
    -0
      app/locales/locales.js
  9. +9
    -10
      app/main.js
  10. +54
    -0
      app/services/auth.js

+ 40
- 16
app/app.vue Ver ficheiro

@@ -6,7 +6,7 @@
font-size: 14px;
line-height: 1.5;
color: #CFD2DA;
background-color: #252830;
background-color: #262B30;
overflow-y: scroll;
}

@@ -14,7 +14,7 @@
color: #0275D8;
}

#header{
#header {
padding: 0;
}

@@ -26,19 +26,43 @@
</style>

<template>
<div id="header" class="container m-t-1">
<nav class="navbar navbar-dark ">
<a class="navbar-brand" href="#/">
<img id="logo" alt="lesspass" class="img-fluid" src="./assets/images/logo.png">
</a>
<a class="navbar-brand" href="#/"> LessPass
</a>
<ul class="nav navbar-nav pull-xs-right">
<li class="nav-item">
<a class="btn btn-primary" href="#/entries">{{ $t('header.login') }}</a>
</li>
</ul>
</nav>
<div>
<div id="header" class="container m-t-1">
<nav class="navbar navbar-dark ">
<a class="navbar-brand" href="#/">
<img id="logo" alt="lesspass" class="img-fluid" src="./assets/images/logo.png">
</a>
<a class="navbar-brand" href="#/"> LessPass
</a>
<ul class="nav navbar-nav pull-xs-right">
<li class="nav-item">
<a class="btn btn-primary" href="#/entries" v-if="!user.authenticated">
{{ $t('header.login') }}
</a>
</li>
<li class="nav-item">
<a v-if="user.authenticated" @click="logout()">
Logout
</a>
</li>
</ul>
</nav>
</div>
<router-view></router-view>
</div>
<router-view></router-view>
</template>
<script>
import auth from './services/auth'
export default {
data: function () {
return {
user: auth.user
}
},
methods: {
logout() {
auth.logout()
}
}
}
</script>

+ 15
- 5
app/components/auth/auth.vue Ver ficheiro

@@ -1,11 +1,21 @@
<template>
<div class="container">
<div class="col-lg-4">
<a v-link="{ path: '/auth/login' }">login</a>
<a v-link="{ path: '/auth/register' }">register</a>
<div class="row m-y-2">
<div class="col-lg-4 col-lg-offset-4">
<router-view></router-view>
</div>
</div>
<div class="col-lg-8">
<router-view></router-view>
<div class="row">
<div class="col-lg-4 col-lg-offset-4">
<p v-if="$route.path=='/auth/login'">
{{$t('login.dont_have_an_account')}}
<a v-link="{ path: '/auth/register' }">{{$t('login.register')}}</a>
</p>
<p v-if="$route.path=='/auth/register'">
{{$t('login.already_have_an_account')}}
<a v-link="{ path: '/auth/login' }">{{$t('login.login')}}</a>
</p>
</div>
</div>
</div>
</template>

+ 34
- 55
app/components/auth/login.vue Ver ficheiro

@@ -1,68 +1,47 @@
<!--<style>
#login .form-control {
background-color: #31353A;
color: #8F9394;
border: 1px solid #31353A;
}
</style>-->
<template>
<div class="panel-heading">
Sign in to your account
</div>
<div class="panel-body">
<form class="form-horizontal" role="form">

<div id="alerts" v-if="messages.length > 0">
<div v-for="message in messages" class="alert alert-{{ message.type }} alert-dismissible" role="alert">
{{ message.message }}
</div>
</div>

<div class="form-group">
<label class="col-md-4 control-label">E-Mail Address</label>
<div class="col-md-6">
<input type="email" class="form-control" v-model="email">
</div>
</div>

<div class="form-group">
<label class="col-md-4 control-label">Password</label>
<div class="col-md-6">
<input type="password" class="form-control" v-model="password">
</div>
</div>

<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<button type="submit" class="btn btn-primary" v-on:click="login">
<i class="fa fa-btn fa-sign-in"></i>Login
</button>

<!--<a class="btn btn-link" v-link="{ path: '/auth/forgot' }">Forgot Your Password?</a>-->
</div>
</div>
</form>
<div id="login" class="p-y-2">
<h2>{{$t('login.login')}}</h2>
<p>{{$t('login.why')}}</p>
<div class="alert alert-danger" v-if="error">
<p>{{{$t('login.credentials_invalids')}}}</p>
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="{{$t('login.enter_email')}}"
v-model="credentials.username">
</div>
<div class="form-group">
<input type="password" class="form-control" placeholder="{{$t('login.enter_password')}}"
v-model="credentials.password">
</div>
<button class="btn btn-primary" @click="submit()">{{$t('login.lets_go')}}</button>
</div>
<!--<input type="text" name="email" v-model="email">
<input type="password" name="password" v-model="password">
<button class="btn btn-primary" v-on:click="login">se connecter</button>-->
</template>
<script>
import auth from '../../services/auth'
export default {
data: function () {
return {
email: '',
password: ''
credentials: {
username: '',
password: ''
},
error: ''
}
},
methods: {
login: function () {
var email = this.email;
var password = this.password;


this.$http.get('http://localhost:8000/api/').then(function (response) {
console.log('success');
console.log(response);
}, function (response) {
console.log('error');
console.log(response)
});


submit() {
var credentials = {
username: this.credentials.username,
password: this.credentials.password
};
auth.login(this, credentials, '/entries')
}
}
}

+ 42
- 1
app/components/auth/register.vue Ver ficheiro

@@ -1,3 +1,44 @@
<!--<style>
#register .form-control {
background-color: #31353A;
color: #8F9394;
border: 1px solid #31353A;
}
</style>-->
<template>
register
<div id="register" class="p-y-2">
<h2>{{$t('login.register')}}</h2>
<div class="form-group m-t-2">
<input type="text" class="form-control" placeholder="{{$t('login.enter_email')}}"
v-model="credentials.username">
</div>
<div class="form-group">
<input type="password" class="form-control" placeholder="{{$t('login.enter_password')}}"
v-model="credentials.password">
</div>
<button class="btn btn-primary" @click="submit()">{{$t('login.create_account')}}</button>
</div>
</template>
<script>
import auth from '../../services/auth'
export default {
data: function () {
return {
credentials: {
username: '',
password: ''
},
error: ''
}
},
methods: {
submit() {
var credentials = {
username: this.credentials.username,
password: this.credentials.password
};

}
}
}
</script>

+ 24
- 2
app/components/entries.vue Ver ficheiro

@@ -1,3 +1,25 @@
<template>
entries
</template>
entries
</template>

<script>
export default {
data: function () {
return {
entries: []
}
},
methods: {
getEntries() {
console.log('make get resquest here');
/*this.$http.get('http://localhost:3001/api/protected/random-quote', (data) => {
this.quote = data;
}, {
// Attach the JWT header
headers: auth.getAuthHeader()
})
.error((err) => console.log(err))*/
}
}
}
</script>

+ 3
- 1
app/components/index.vue Ver ficheiro

@@ -20,7 +20,9 @@
import LesspassFooter from './footer.vue';

export default {
data :{},
data: function () {
return {}
},
components: {
LesspassHeadlines,
LesspassJumbotron,


+ 15
- 10
app/components/password-generator.vue Ver ficheiro

@@ -1,27 +1,30 @@
<style>
<!--<style>
#passwordGenerator .form-control {
background-color: #434857;
color: white;
border: 1px solid #434857;
background-color: #31353A;
color: #8F9394;
border: 1px solid #31353A;
}
</style>
</style>-->
<template>
<div class="container m-y-3">
<form id="passwordGenerator">
<div class="form-group row">
<label for="email" class="sr-only form-control-label">{{ $t('passwordgenerator.email') }}</label>
<div class="col-sm-3">
<input type="email" class="form-control" id="email" placeholder="{{ $t('passwordgenerator.email') }}" v-model="email"
<input type="email" class="form-control" id="email"
placeholder="{{ $t('passwordgenerator.email') }}" v-model="email"
v-on:blur="updateMasterPassword">
</div>
<label for="password" class="sr-only form-control-label">{{ $t('passwordgenerator.password') }}</label>
<div class="col-sm-3">
<input type="password" class="form-control" id="password" placeholder="{{ $t('passwordgenerator.password') }}"
<input type="password" class="form-control" id="password"
placeholder="{{ $t('passwordgenerator.password') }}"
v-model="password" v-on:blur="updateMasterPassword">
</div>
<label for="site" class="sr-only form-control-label">{{ $t('passwordgenerator.site') }}</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="site" placeholder="{{ $t('passwordgenerator.site_placeholder') }}"
<input type="text" class="form-control" id="site"
placeholder="{{ $t('passwordgenerator.site_placeholder') }}"
v-model="site">
</div>
<label for="generatedPassword" class="sr-only form-control-label">Generated Password</label>
@@ -41,7 +44,8 @@
<div class="col-lg-12">
<div class="checkbox">
<label>
<input type="checkbox" v-model="showAdvancedOptions"> {{ $t('passwordgenerator.advanced_options') }}
<input type="checkbox" v-model="showAdvancedOptions"> {{
$t('passwordgenerator.advanced_options') }}
</label>
</div>
</div>
@@ -67,7 +71,8 @@
</div>
</div>
<div class="form-group row" v-if="showAdvancedOptions">
<label for="passwordLength" class="col-xs-2 col-sm-1 form-control-label">{{ $t('passwordgenerator.length') }}</label>
<label for="passwordLength" class="col-xs-2 col-sm-1 form-control-label">{{
$t('passwordgenerator.length') }}</label>
<div class="col-xs-8 col-sm-4">
<input id="passwordLength" type="range" value="12" min="6" max="64" v-model="passwordInfo.length"
class="form-control">


+ 26
- 0
app/locales/locales.js Ver ficheiro

@@ -62,6 +62,20 @@ const locales = {
"q_pricing": "Is LessPass free?",
"a_pricing_free": "LessPass is free and always will be.",
"a_pricing_enterprise": "LessPass Enterprise will add support for <abbr title='Lightweight Directory Access Protocol'>LDAP</abbr> and double-authentication for companies."
},
"login": {
"login": "login",
"Login": "Log In",
"register": "register",
"Register": "Register",
"why": "Manage your sites with online mode",
"enter_email": "Enter your email",
"enter_password": "Enter your password",
"lets_go": "Let's go !",
"dont_have_an_account": "Don't have an account ?",
"already_have_an_account": "Already have an account ?",
"create_account": "Create an account",
"credentials_invalids": "The email address or password you entered is not valid. If you don't have an account yet, you can <a href='#/auth/register'>register</a>."
}
},
"fr": {
@@ -128,6 +142,18 @@ const locales = {
"q_pricing": "Est ce que LessPass est gratuit ?",
"a_pricing_free": "LessPass est gratuit et le sera toujours.",
"a_pricing_enterprise": "LessPass Enterprise, avec le support <abbr title='Lightweight Directory Access Protocol'>LDAP</abbr> et la double authentication, sera payante pour les enterprises."
},
"login": {
"login": "Connectez-vous",
"register": "S'enregistrer",
"why": "Gérez vos mots de passe avec le mode connecté",
"enter_email": "Entrez votre email",
"enter_password": "Entrez votre mot de passe",
"lets_go": "C'est parti !",
"dont_have_an_account": "Vous n'avez pas encore de compte ?",
"already_have_an_account": "Vous avez déjà un compte ?",
"create_account": "Créez un compte",
"credentials_invalids": "L' adresse e-mail et mot de passe ne sont pas valides. Si vous ne possédez pas encore de compte, vous pouvez vous <a href='#/auth/register'>inscrire</a>."
}
}
};


+ 9
- 10
app/main.js Ver ficheiro

@@ -1,8 +1,8 @@
import Vue from 'vue'
import Router from 'vue-router';
import Resource from 'vue-resource';

import i18n from 'vue-i18n';

import locales from './locales/locales';
import App from './app.vue';
import IndexView from './components/index.vue';
@@ -10,24 +10,24 @@ import AuthView from './components/auth/auth.vue';
import LoginView from './components/auth/login.vue';
import RegisterView from './components/auth/register.vue';
import EntriesView from './components/entries.vue';
import auth from './services/auth';
Vue.use(Resource);
Vue.use(Router);


var browserLanguage = (navigator.language || navigator.browserLanguage).split('-')[0];
var lang = browserLanguage in locales ? browserLanguage : 'en';

Vue.use(i18n, {
lang: lang,
locales: locales
});


Vue.use(Resource);

//$http.defaults.headers.post['X-CSRFToken'] = $cookies.get('csrftoken');
//Vue.http.headers.common['X-CSRF-TOKEN'] = document.querySelector('#token').getAttribute('value');
Vue.http.headers.common['Authorization'] = 'Bearer ' + localStorage.getItem('token');

Vue.use(Router);
auth.checkAuth();

var router = new Router();
export var router = new Router();

router.map({
'/': {
@@ -61,8 +61,7 @@ router.redirect({
router.start(App, '#app');

router.beforeEach(function (transition) {
var authenticated = false;
if (transition.to.auth && !authenticated) {
if (transition.to.auth && !auth.user.authenticated) {
transition.redirect('/auth/login')
} else {
transition.next()


+ 54
- 0
app/services/auth.js Ver ficheiro

@@ -0,0 +1,54 @@
import {router} from '../main'

export default {
user: {
authenticated: false
},

login(context, credentials, redirect) {
context.$http.post('/api/sessions/', credentials).then(
function (data) {
localStorage.setItem('token', data.token);
this.user.authenticated = true;
if (redirect) {
router.go(redirect)
}
},
function (error) {
context.error = true;
}
);
},

register(context, user, redirect) {
context.$http.post('/api/users/', user).then(
function (data) {
localStorage.setItem('token', data.token);
this.user.authenticated = true;
if (redirect) {
router.go(redirect)
}
},
function (error) {
context.error = true;
}
);
},

logout() {
localStorage.removeItem('token');
this.user.authenticated = false;
router.go('/')
},

checkAuth() {
var jwt = localStorage.getItem('token');
this.user.authenticated = !!jwt;
},

getAuthHeader() {
return {
'Authorization': 'Bearer ' + localStorage.getItem('token')
}
}
}

Carregando…
Cancelar
Guardar