finish unlock

This commit is contained in:
RainSun 2020-02-20 18:20:02 +08:00
parent b77dab7f08
commit 909fd6ae6a
8 changed files with 249 additions and 241 deletions

View File

@ -16,6 +16,7 @@
"vue-clipboard2": "^0.3.1", "vue-clipboard2": "^0.3.1",
"vue-material": "^1.0.0-beta-11", "vue-material": "^1.0.0-beta-11",
"vue-router": "^3.1.5", "vue-router": "^3.1.5",
"vue-svg-icon": "^1.2.9",
"vuex": "^3.1.2" "vuex": "^3.1.2"
}, },
"devDependencies": { "devDependencies": {

View File

@ -1,6 +1,6 @@
<template> <template>
<div id="app"> <div id="app">
<div class="bg"></div> <icon class="bg" name="canary"></icon>
<router-view/> <router-view/>
</div> </div>
</template> </template>
@ -126,15 +126,13 @@ button {
user-select: none; user-select: none;
} }
.bg { .bg {
position: fixed; position: absolute;
top: 0; top: 50%;
left: 0; left: 50%;
z-index: -100; z-index: -100;
height: 100%; height: 5rem;
width: 100%; width: 5rem;
object-fit: cover; margin-top: -2.5rem;
background-image: linear-gradient(to bottom, #eaeaea, #ababab); margin-left: -2.5rem;
background-repeat: no-repeat;
background-size: 100% 100%;
} }
</style> </style>

BIN
src/assets/canary.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -4,6 +4,10 @@ import './registerServiceWorker'
import router from './router' import router from './router'
import store from './store' import store from './store'
// icon-loader
import Icon from 'vue-svg-icon/Icon.vue'
Vue.component('icon', Icon);
// material // material
import VueMaterial from 'vue-material' import VueMaterial from 'vue-material'
import 'vue-material/dist/vue-material.min.css' import 'vue-material/dist/vue-material.min.css'

1
src/svg/canary.svg Normal file
View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1582191167349" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3270" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M921.6 716.75904L415.46752 210.66752a136.25344 136.25344 0 0 0-96.54272-39.99744c-70.93248 0-128.53248 54.272-135.19872 123.43296L102.4 375.43936h86.12864C210.59584 506.39872 294.57408 616.09984 409.6 673.49504v179.84512h68.27008V700.34432a405.18656 405.18656 0 0 0 68.25984 13.70112v139.30496H614.4V716.75904h307.2zM448.93184 340.6336L620.2368 511.95904h-39.95648c-75.27424 0-136.54016-61.22496-136.54016-136.52992-0.01024-12.12416 2.12992-23.63392 5.19168-34.79552z m-198.26688-33.46432a68.32128 68.32128 0 0 1 68.25984-68.22912c18.19648 0 35.36896 7.09632 48.27136 19.99872l28.4672 28.4672a202.37312 202.37312 0 0 0-20.20352 88.03328c0 112.92672 91.86304 204.8 204.8 204.8h108.22656l68.27008 68.25984H592.00512c-188.20096 0-341.34016-153.1392-341.34016-341.32992z" p-id="3271" fill="#bbdefb"></path></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -45,10 +45,16 @@
<md-icon>settings</md-icon> <md-icon>settings</md-icon>
<span class="md-list-item-text">Settings</span> <span class="md-list-item-text">Settings</span>
</md-list-item> </md-list-item>
<md-list-item v-clipboard:copy="web_addr" v-clipboard:success="onCopyUrl" v-clipboard:error="onErrorUrl"> <md-list-item v-clipboard:copy="web_addr" v-clipboard:success="onCopyUrl" v-clipboard:error="onErrorUrl">
<md-icon>reply</md-icon> <md-icon>reply</md-icon>
<span class="md-list-item-text">Share</span> <span class="md-list-item-text">Share</span>
</md-list-item> </md-list-item>
<md-list-item>
<md-icon>beenhere</md-icon>
<span class="md-list-item-text">Lock Now</span>
</md-list-item>
</md-list> </md-list>
</md-app-drawer> </md-app-drawer>
@ -72,7 +78,6 @@
</md-speed-dial> </md-speed-dial>
<md-snackbar md-position="center" :md-active.sync="show_snackbar" md-persistent> <md-snackbar md-position="center" :md-active.sync="show_snackbar" md-persistent>
<span>{{ snakebar_msg }}</span> <span>{{ snakebar_msg }}</span>
<md-button class="md-primary" @click="show_snackbar = false" v-if="snakebar_msg=='复制失败'">重试</md-button>
</md-snackbar> </md-snackbar>
</md-app-content> </md-app-content>
</md-app> </md-app>
@ -142,12 +147,12 @@ export default {
this.turnToUnlock('密码超时'); this.turnToUnlock('密码超时');
} }
} else { } else {
// //
this.show_list = []; this.turnToUnlock('无密码');
this.unlock = false;
} }
console.log(this.show_list.length != 0 ? '密码本存在' : '空密码本'); console.log(this.show_list.length != 0 ? '密码本存在' : '空密码本');
console.log(this.unlock ? '已解锁' : '未解锁'); console.log(this.unlock ? '已解锁' : '未解锁');
}, },
// //
@ -184,15 +189,17 @@ export default {
// //
turnToUnlock(type) { turnToUnlock(type) {
console.log(type); console.log(type);
let main_code = '10aeff'; // let main_code = '10aeff';
let main_code_aes = encryptMainCode(main_code); // let main_code_aes = encryptMainCode(main_code);
let row_pwd = { // let row_pwd = {
main_code: main_code_aes, // main_code: main_code_aes,
create_time: new Date().getTime() // create_time: new Date().getTime()
}; // };
this.setRowPwd([row_pwd, this]); // this.setRowPwd([row_pwd, this]);
console.log('主密码设置完成返回init'); // console.log('init');
this.init(); // this.init();
if(type == '密码超时') this.$router.push({ name: "Unlock", params: { msg: 'Password validity period has expired, please re-enter' } })
else this.$router.push('/unlock')
}, },
// //
@ -228,7 +235,7 @@ export default {
// //
onErrorUrl(e) { onErrorUrl(e) {
this.snakebar_msg = '复制失败'; this.snakebar_msg = '复制失败,夸克等浏览器复制成功仍会显示失败';
this.show_snackbar = true; this.show_snackbar = true;
} }
}, },

View File

@ -1,188 +1,179 @@
<template> <template>
<div class="home" ref="home"> <div class="unlock">
<md-app md-waterfall md-mode="fixed"> <md-toolbar class="md-primary">
<md-app-toolbar class="md-primary"> <h3 class="md-title" style="flex: 1">{{ is_create ? 'Create Password' : 'Unlock' }}</h3>
<div class="md-toolbar-section-start"> </md-toolbar>
<md-button class="md-icon-button" @click="menuVisible = !menuVisible"> <icon class="logo" name="canary"></icon>
<md-icon>menu</md-icon> <p class="md-title center">{{ is_create ? 'Create New Password' : 'Unlock Canary Codebook' }}</p>
</md-button> <md-field class="input-box" :class="messageClass">
<span class="md-title">Codebook</span> <label>{{ is_create ? 'New Password' : 'Unlock Password' }}</label>
</div> <md-input v-model="pwd" type="password"></md-input>
<div class="md-toolbar-section-end"> <span class="md-error">{{ err_msg }}</span>
<md-button class="md-icon-button"> </md-field>
<md-icon>search</md-icon> <md-field class="input-box" :class="messageClass" v-if="is_create">
</md-button> <label>Repeat Password</label>
<md-menu md-align-trigger> <md-input v-model="repeat" type="password"></md-input>
<md-button md-menu-trigger class="md-icon-button"> <span class="md-error">{{ err_msg }}</span>
<md-icon>more_vert</md-icon> </md-field>
</md-button> <md-button class="md-raised md-primary center" @click="judgePwd()">Enter</md-button>
<md-menu-content> <md-dialog-confirm
<md-menu-item>Alphabetically</md-menu-item> :md-active.sync="show_dialog"
<md-menu-item>Recently Used</md-menu-item> md-title="Confirm you new password?"
</md-menu-content> md-content="The password will not be modified after submission, please make sure you dont tell anyone this password."
</md-menu> md-confirm-text="Agree"
</div> md-cancel-text="Disagree"
</md-app-toolbar> @md-cancel="onCancel"
@md-confirm="submit"
<md-app-drawer :md-active.sync="menuVisible"> />
<div class="drawer-banner"> <md-snackbar md-position="center" :md-active.sync="show_snackbar" md-persistent>
<md-icon class="default-avatar md-size-2x">face</md-icon> <span>{{ snakebar_msg }}</span>
<p class="md-title">Canary Codebook</p> </md-snackbar>
<p class="md-caption">zhaoyingbo@live.cn</p> </div>
</div>
<md-list>
<md-list-item>
<md-icon>person</md-icon>
<span class="md-list-item-text">Account</span>
</md-list-item>
<md-list-item>
<md-icon>help</md-icon>
<span class="md-list-item-text">FAQ</span>
</md-list-item>
<md-list-item>
<md-icon>question_answer</md-icon>
<span class="md-list-item-text">Provide Feedback</span>
</md-list-item>
<md-list-item>
<md-icon>settings</md-icon>
<span class="md-list-item-text">Settings</span>
</md-list-item>
<md-list-item>
<md-icon>reply</md-icon>
<span class="md-list-item-text">Share</span>
</md-list-item>
</md-list>
</md-app-drawer>
<md-app-content>
<md-empty-state
md-icon="devices_other"
md-label="Create your first code"
md-description="Creating code, you'll be able to upload your information to the server and save it."
v-if="test_data.length == 0"
>
<md-button class="md-primary md-raised">Create first code</md-button>
</md-empty-state>
<div class="code-card" v-for="(code, index) in test_data" :key="index">
<p class="md-title">{{code.title}}</p>
<p class="md-caption">{{code.user_name}}</p>
</div>
<md-speed-dial class="md-bottom-right" v-if="test_data.length != 0">
<md-speed-dial-target>
<md-icon>add</md-icon>
</md-speed-dial-target>
</md-speed-dial>
</md-app-content>
</md-app>
</div>
</template> </template>
<script> <script>
// @ is an alias to /src // @ is an alias to /src
import { mapState, mapActions } from "vuex"; import { mapState, mapActions } from 'vuex';
import { encrypt, decrypt, encryptMainCode, decryptMainCode } from '@/utils/aes.js';
export default { export default {
name: "Home", name: 'Unlock',
data() { data() {
return { return {
menuVisible: false, pwd: '',
has_data: false, repeat: '',
clientHeight: "", is_err: false,
test_data: [ err_msg: '',
{ show_dialog: false,
open_count:0, is_create: false,
title:'QQ', show_snackbar: false,
user_name:'1144131090', snakebar_msg:''
password:'test', };
node:'测试用', },
},{ computed: {
open_count:0, ...mapState(['row_data']),
title:'微信', messageClass() {
user_name:'15143211127', return {
password:'test', 'md-invalid': this.is_err
node:'测试用', };
},{ }
open_count:0, },
title:'QQ', methods: {
user_name:'1144131090', ...mapActions(['setRowPwd']),
password:'test',
node:'测试用', //
},{ init() {
open_count:0, // vuex
title:'QQ', this.$store.replaceState(Object.assign(this.$store.state, JSON.parse(localStorage.getItem('storeState'))));
user_name:'1144131090', //
password:'test', this.is_create = this.row_data ? false : true;
node:'测试用', // SnakeBar
}, if (this.$route.params.msg) {
] //
}; this.snakebar_msg = this.$route.params.msg
}, this.show_snackbar = true
computed: { }
...mapState([]) },
},
methods: { //
...mapActions([]), judgePwd() {
changeFixed(clientHeight) { //
// if (this.pwd.trim().length == 0) {
// console.log(clientHeight); this.is_err = true;
this.$refs.home.children[0].style.minHeight = clientHeight + "px"; this.err_msg = 'Password can not be none';
} console.log('密码为空拦截');
}, return;
created() {}, }
mounted() { //
// if (this.row_data) {
this.clientHeight = `${document.documentElement.clientHeight}`; //
//document.body.clientWidth; let test_decode = decrypt(this.pwd, this.row_data);
window.onresize = function temp() { //
this.clientHeight = `${document.documentElement.clientHeight}`; if (test_decode) {
}; // ,locolstorage
}, this.submit();
watch: { } else {
// `clientHeight` //
clientHeight: function() { this.is_err = true;
this.changeFixed(this.clientHeight); this.err_msg = 'Wrong password';
} console.log('密码输入错误拦截');
}, }
beforeDestroy() {}, } else {
components: {} //
if (this.pwd == this.repeat) {
//
this.show_dialog = true;
} else {
//
this.is_err = true;
this.err_msg = 'The two passwords do not match';
console.log('密码两次输入不一致拦截');
}
}
},
//
onCancel() {
console.log('用户点击取消');
},
//
submit() {
let main_code_aes = encryptMainCode(this.pwd);
let row_pwd = {
main_code: main_code_aes,
create_time: new Date().getTime()
};
this.setRowPwd([row_pwd, this]);
console.log('主密码设置完成返回Home');
this.$router.replace('/');
}
},
created() {
this.init();
},
mounted() {},
watch: {
// `pwd`
pwd: function() {
this.is_err = false;
this.err_msg = '';
},
// `repeat`
repeat: function() {
this.is_err = false;
this.err_msg = '';
}
},
beforeDestroy() {},
components: {}
}; };
</script> </script>
<style scoped lang="scss" type="text/scss"> <style scoped lang="scss" type="text/scss">
@import "../../style/main"; @import '../../style/main';
.home { .unlock {
width: 100%; width: 100%;
// max-width: 500px; min-height: 100%;
min-height: 100%; background: #fff;
background: #fff; .logo {
// margin: 0 auto; margin: 0 auto;
.drawer-banner { display: block;
padding: 1rem 0.3rem 0.3rem 0.3rem; height: 5rem;
box-sizing: border-box; width: 5rem;
background: $main-color; }
color: #fff; .center {
.default-avatar { margin: 0 auto;
color: #fff; text-align: center;
margin-bottom: 0.3rem; display: block;
} }
.md-caption { .input-box {
color: #fbfbfb; width: 70%;
} max-width: 350px;
} margin: 0.5rem auto;
.code-card { }
padding: .3rem 0; .md-raised {
border-bottom: 1px #eee solid; margin-top: 1rem;
} }
} }
// Demo purposes only </style>
.md-drawer {
width: 240px;
max-width: calc(100vw - 125px);
}
</style>

View File

@ -1,41 +1,47 @@
this.show_list = [ this.show_list = [{
{ open_count: 1,
open_count: 1, title: 'QQ',
title: 'QQ', user_name: '1144131090',
user_name: '1144131090', password: 'test',
password: 'test', node: '测试用'
node: '测试用' },
}, {
{ open_count: 2,
open_count: 2, title: '微信',
title: '微信', user_name: '15143211127',
user_name: '15143211127', password: 'test',
password: 'test', node: '测试用'
node: '测试用' },
}, {
{ open_count: 3,
open_count: 3, title: 'WIFI',
title: 'WIFI', user_name: 'admin',
user_name: 'admin', password: 'test',
password: 'test', node: '测试用'
node: '测试用' },
}, {
{ open_count: 4,
open_count: 4, title: 'WeGame',
title: 'WeGame', user_name: '1144131090',
user_name: '1144131090', password: 'test',
password: 'test', node: '测试用'
node: '测试用' }
} ];
];
test() { function test() {
// //
// let main_code = '10aeff' // let main_code = '10aeff'
// let data_aes = encrypt(main_code, this.show_list); // let data_aes = encrypt(main_code, this.show_list);
// if(!this.row_data) this.setRowData([data_aes, this]) // if(!this.row_data) this.setRowData([data_aes, this])
// let main_code_aes = encryptMainCode(main_code) // let main_code_aes = encryptMainCode(main_code)
// if(!this.row_pwd) this.setRowPwd([main_code_aes, this]) // if(!this.row_pwd) this.setRowPwd([main_code_aes, this])
// let main_code_decrpt = decryptMainCode(main_code_aes) // let main_code_decrpt = decryptMainCode(main_code_aes)
// let data_decrpt = decrypt(main_code_decrpt, data_aes) // let data_decrpt = decrypt(main_code_decrpt, data_aes)
// console.log(data_aes, main_code_aes, main_code_decrpt,data_decrpt) // console.log(data_aes, main_code_aes, main_code_decrpt,data_decrpt)
}, }
let test_encode = encrypt('10aeff', '这是一段测试文本');
console.log('加密后', test_encode)
let test_decode = decrypt('10aefs', test_encode)
console.log('解密后', test_decode)
console.log('类型', typeof(test_decode)) // 密码错误就是空字符串