ソースを参照

include vuejs and move to dark template

pull/44/head
Guillaume Vincent 9年前
コミット
8d759cfcb8
11個のファイルの変更275行の追加101行の削除
  1. +11
    -0
      app/app.js
  2. +0
    -72
      app/app.old.js
  3. +20
    -0
      app/components/bootstrap-hr.vue
  4. +126
    -0
      app/components/password-generator.vue
  5. +25
    -6
      package.json
  6. +33
    -0
      static/css/styles.scss
  7. バイナリ
      static/images/C:\Users\19011246\workspace\lesspass\static\images\logo.png
  8. バイナリ
      static/images/C:\Users\19011246\workspace\lesspass\static\images\logo2.png
  9. バイナリ
      static/images/logo.png
  10. +28
    -23
      static/images/logo.svg
  11. +32
    -0
      static/index.html

+ 11
- 0
app/app.js ファイルの表示

@@ -0,0 +1,11 @@
import Vue from 'vue';
import PasswordGenerator from './components/password-generator.vue';
import BootstrapHr from './components/bootstrap-hr.vue';

new Vue({
el: 'body',
components: {
passwordGenerator: PasswordGenerator,
bootstrapHr: BootstrapHr
}
});

+ 0
- 72
app/app.old.js ファイルの表示

@@ -1,72 +0,0 @@
import lesspass from '../app/lesspass';
import angular from 'angular';

import Clipboard from 'clipboard';

window.jQuery = $ = require('jquery');
var bootstrap = require('bootstrap/dist/js/bootstrap');

class lesspassController {
constructor($scope) {
var vm = this;

this.password = '';
this.site = {
site_name: '',
password_length: 12,
password_types: ['lowercase', 'uppercase', 'numbers', 'symbols'],
counter: 1
};

$scope.$watch(function () {
return vm.password;
}, function () {
vm.updatePassword();
});

$scope.$watchCollection(function () {
return vm.site;
}, function () {
vm.updatePassword();
});

var clipboard = new Clipboard('#copy-btn');
clipboard.on('success', function (e) {
if (vm.password && vm.site.site_name) {
var t = $('#copy-btn').tooltip({title: 'Copié'});
t.tooltip('show');
e.clearSelection();
}
});

clipboard.on('error', function (e) {
var passwordGenerated = document.getElementById("password_generated");
var t = $(passwordGenerated).tooltip({title: 'Cmd + C pour copier le mot de passe'});
t.tooltip('show');
});

this.displayHelp = false;
}

updatePasswordTypes(type) {
var passwordTypes = this.site.password_types;
var indexOfId = passwordTypes.indexOf(type);
if (indexOfId == -1) {
passwordTypes.push(type)
} else {
passwordTypes.splice(indexOfId, 1)
}
this.updatePassword();
}

updatePassword() {
if (this.password && this.site.site_name) {
this.generatedPassword = lesspass.create_password(this.password, this.site);
}
}
}


angular
.module('app', [])
.controller('lesspassController', lesspassController);

+ 20
- 0
app/components/bootstrap-hr.vue ファイルの表示

@@ -0,0 +1,20 @@
<style>
hr {
margin-top: 1em;
margin-bottom: 3em;
border: 0 none -moz-use-text-color;
border-top: 1px solid #434857;
-moz-border-top-colors: none;
-moz-border-right-colors: none;
-moz-border-bottom-colors: none;
-moz-border-left-colors: none;
border-image: none;
}
</style>
<template>
<div class="container">
<div class="col-md-6 col-md-offset-3">
<hr>
</div>
</div>
</template>

+ 126
- 0
app/components/password-generator.vue ファイルの表示

@@ -0,0 +1,126 @@
<style>
#passwordGenerator input {
background-color: #434857;
color: white;
border: 1px solid #434857;
}
</style>

<template>
<div class="container">

<form class="form-inline" id="passwordGenerator">
<div class="m-t-1">
<div class="form-group">
<label class="sr-only" for="email">Adresse email</label>
<input type="email" class="form-control" id="email" placeholder="Email" v-model="email">
</div>
<div class="form-group">
<label class="sr-only" for="password">Mot de passe</label>
<input type="password" class="form-control" id="password" placeholder="Mot de passe"
v-model="password">
</div>
<div class="form-group">
<label class="sr-only" for="site">Site</label>
<input type="text" class="form-control" id="site" placeholder="Site (ex: Facebook)"
v-model="site">
</div>
<div class="form-group">
<label class="sr-only" for="generatedPassword">Mot de passe unique</label>
<div class="input-group">
<input type="text" id="generatedPassword" class="form-control" v-model="generatedPassword">
<span class="input-group-btn">
<button id="copyBtn" data-clipboard-target="#generatedPassword"
class="btn btn-primary" type="button">
Copier
</button>
</span>
</div>
</div>
</div>
<div class="m-t-1">
<div class="checkbox">
<label>
<input type="checkbox" v-model="showAdvancedOptions"> Options avancées
</label>
</div>
</div>
<div class="m-t-1" v-if="showAdvancedOptions">
<div class="form-group">
<label class="checkbox-inline">
<input type="checkbox" id="lowercaseCheckbox" value="lowercase" v-model="passwordTypes" checked>
minuscules (a-z)
</label>
<label class="checkbox-inline">
<input type="checkbox" id="uppercaseCheckbox" value="uppercase" v-model="passwordTypes" checked>
MAJUSCULES (A-Z)
</label>
<label class="checkbox-inline">
<input type="checkbox" id="numbersCheckbox" value="numbers" v-model="passwordTypes" checked>
nombres (0-9)
</label>
<label class="checkbox-inline">
<input type="checkbox" id="symbolsCheckbox" value="symbols" v-model="passwordTypes" checked>
caractères spéciaux (@&%?)
</label>
</div>
</div>
<div class="m-t-1" v-if="showAdvancedOptions">
<div class="form-group">
<label for="passwordLength">Longueur</label>
<input id="passwordLength" type="range" value="12" min="6" max="64" v-model="length"
class="form-control"> {{ length }}
</div>
</div>
</form>

</div>
</template>

<script lang="babel">
import crypto from 'crypto';
import lesspass from '../lesspass';

import Clipboard from 'clipboard';


export default {
data: function () {
return {
email: '',
password: '',
site: '',
length: 12,
counter: 1,
passwordTypes: ["lowercase", "uppercase", "numbers", "symbols"],
showAdvancedOptions: false
}
},
computed: {
generatedPassword: function () {
var generatedPassword;
if (this.email && this.password && this.site) {
var masterPassword = crypto.pbkdf2Sync(this.email, this.password, 10, 64, 'sha256').toString('hex');

generatedPassword = lesspass.create_password(masterPassword, {
site_name: this.site,
password_length: this.length,
password_types: this.passwordTypes,
counter: this.counter
});
}
return generatedPassword;
}
}
}


var cb = new Clipboard('#copyBtn');
cb.on('success', function (e) {
e.clearSelection();
});

cb.on('error', function (e) {

});
</script>

+ 25
- 6
package.json ファイルの表示

@@ -10,8 +10,9 @@
"build:production": "npm prune && npm install && npm run lint && npm test && npm run build",
"build": "npm-run-all clean build:static build:app",
"clean": "rimraf dist && mkdir dist",
"build:static": "npm-run-all copy:html build:css",
"build:static": "npm-run-all copy:html copy:images build:css",
"copy:html": "cpy 'static/*.html' dist",
"copy:images": "cpy 'static/images/*.png' dist/images/",
"build:css": "node-sass static/css/styles.scss dist/css/styles.css",
"build:app": "browserify -e ./app/app.js -o ./dist/app.js",
"prestart": "npm run build",
@@ -35,14 +36,14 @@
},
"homepage": "https://github.com/guillaumevincent/lesspass#readme",
"dependencies": {
"angular": "^1.4.8",
"bootstrap": "^4.0.0-alpha.2",
"clipboard": "^1.5.5",
"jquery": "^2.1.4"
"clipboard": "^1.5.5"
},
"devDependencies": {
"babel-core": "latest",
"babel-preset-es2015": "latest",
"babel-core": "^6.3.26",
"babel-plugin-transform-runtime": "^6.3.13",
"babel-preset-es2015": "^6.3.13",
"babel-runtime": "^5.8.34",
"babelify": "latest",
"browserify": "latest",
"cpy": "latest",
@@ -53,6 +54,10 @@
"nodemon": "latest",
"npm-run-all": "latest",
"rimraf": "latest",
"vue": "^1.0.12",
"vue-hot-reload-api": "^1.2.2",
"vueify": "^8.0.0",
"vueify-insert-css": "^1.0.0",
"watch": "latest",
"watchify": "latest"
},
@@ -68,6 +73,20 @@
{
"presets": [
"es2015"
],
"plugins": [
"transform-runtime"
]
}
],
[
"vueify",
{
"presets": [
"es2015"
],
"plugins": [
"transform-runtime"
]
}
]


+ 33
- 0
static/css/styles.scss ファイルの表示

@@ -1,3 +1,36 @@
@import '../../node_modules/bootstrap/scss/bootstrap';

body {
font-family: "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
line-height: 1.5;
color: #CFD2DA;
background-color: #252830;
padding-bottom: 2em;
}

#header {
#logo-link {
margin: 0 auto;
width: 200px;
height: 45px;

#logo {
width: inherit;
height: inherit;
}
}
}

#headlines {
padding-top: 2em;
padding-bottom: 1em;
}

.blue {
color: #0275D8;
}

.jumbotron {
color: black;
}

バイナリ
static/images/C:\Users\19011246\workspace\lesspass\static\images\logo.png ファイルの表示

変更前 変更後
幅: 380  |  高さ: 74  |  サイズ: 4.9 KiB

バイナリ
static/images/C:\Users\19011246\workspace\lesspass\static\images\logo2.png ファイルの表示

変更前 変更後
幅: 380  |  高さ: 74  |  サイズ: 4.9 KiB

バイナリ
static/images/logo.png ファイルの表示

変更前 変更後
幅: 360  |  高さ: 98  |  サイズ: 6.2 KiB 幅: 400  |  高さ: 90  |  サイズ: 5.5 KiB

+ 28
- 23
static/images/logo.svg ファイルの表示

@@ -9,16 +9,16 @@
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="180"
height="37"
viewBox="0 0 180 37"
width="200"
height="45"
viewBox="0 0 200 45"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
inkscape:version="0.48.4 r9939"
sodipodi:docname="logo.svg"
inkscape:export-filename="C:\Users\19011246\workspace\lesspass\static\images\logo.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
inkscape:export-filename="/home/guillaume/workspace/lesspass/static/images/logo.png"
inkscape:export-xdpi="180"
inkscape:export-ydpi="180">
<defs
id="defs4" />
<sodipodi:namedview
@@ -29,15 +29,15 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.6568543"
inkscape:cx="80.784639"
inkscape:cx="56.566232"
inkscape:cy="2.3568043"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1680"
inkscape:window-height="988"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-width="1366"
inkscape:window-height="744"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1"
units="px" />
<metadata
@@ -56,23 +56,28 @@
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1015.3622)">
transform="translate(0,-1007.3622)">
<path
style="fill:#f9f9f9"
d="m 3.5355339,1040.233 c 0,-4.2478 0,-8.4938 0,-12.7415 1.2566829,0 2.5133651,0 3.7700482,0 0,2.6815 0,5.3616 0,8.042 9.6713189,0 19.3426549,0 29.0139809,0 0,-2.6804 0,-5.3605 0,-8.042 1.282485,0 2.564912,0 3.847367,0 0,4.2476 0,8.4937 0,12.7415 -12.210478,0 -24.420921,0 -36.6313961,0 z"
style="fill:#cfd2da;fill-opacity:1"
d="m 2,1036.233 c 0,-4.2478 0,-8.4938 0,-12.7416 1.2566829,0 2.5133651,0 3.7700482,0 0,2.6816 0,5.3617 0,8.0421 9.6713188,0 19.3426548,0 29.0139808,0 0,-2.6804 0,-5.3605 0,-8.0421 1.282485,0 2.564912,0 3.847367,0 0,4.2477 0,8.4938 0,12.7416 -12.210478,0 -24.420921,0 -36.631396,0 z"
id="path3347"
inkscape:connector-curvature="0" />
inkscape:connector-curvature="0"
inkscape:export-xdpi="179.79413"
inkscape:export-ydpi="179.79413" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:20px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;"
x="54.947002"
y="1041.6552"
style="font-size:20px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#cfd2da;fill-opacity:1;stroke:none;font-family:sans-serif"
x="47.091797"
y="1040.5848"
id="text3356"
sodipodi:linespacing="125%"><tspan
sodipodi:linespacing="125%"
inkscape:export-filename="/home/guillaume/workspace/lesspass/static/images/path3347.png"
inkscape:export-xdpi="179.79413"
inkscape:export-ydpi="179.79413"><tspan
sodipodi:role="line"
id="tspan3358"
x="54.947002"
y="1041.6552"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:30px;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#f9f9f9;">lesspass</tspan></text>
x="47.091797"
y="1040.5848"
style="font-size:30px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#cfd2da;fill-opacity:1;font-family:Open Sans;-inkscape-font-specification:Open Sans Bold">LessPass</tspan></text>
</g>
</svg>

+ 32
- 0
static/index.html ファイルの表示

@@ -8,6 +8,38 @@
<link rel="icon" type="image/png" href="https://lesspass.com/images/favicon.png">
</head>
<body>
<div id="header">
<div class="container text-xs-center">
<div id="logo-link">
<a href="http://lesspass.com">
<img id="logo" alt="lesspass" class="img-fluid" src="images/logo.png">
</a>
</div>
</div>
</div>
<div id="headlines" class="container text-xs-center">
<h1 class="blue">Gérez vos mots de passe en toute confiance</h1>
<h2>LessPass ne mémorise pas vos mots de passe, et vous non plus !</h2>
</div>
<bootstrap-hr></bootstrap-hr>
<div class="container">
<div class="jumbotron">
<div class="row">
<div class="col-lg-12">
<p class="lead">
<a href="https://lesspass.com/">LessPass</a> ne sauvegarde pas vos mots de passe, il les regénère à
chaque fois que vous en avez besoin. Chaque mot de passe est unique et propre à chaque site. Tout ce
dont vous avez besoin c'est de vous souvenir d'un seul mot de passe, et LessPass fait le reste.
</p>
<p class="lead">
Comme LessPass ne sauvegarde pas vos mots de passe, il n'y a rien à voler.
</p>
</div>
</div>
</div>
</div>
<bootstrap-hr></bootstrap-hr>
<password-generator></password-generator>
<script src="app.js"></script>
</body>
</html>

読み込み中…
キャンセル
保存