mirror of
https://github.com/seiichiro0185/sailotp.git
synced 2024-11-21 15:29:42 +00:00
Finished up QR-Code Reader Integration
This commit is contained in:
parent
e74749642f
commit
965c7a382e
9 changed files with 165 additions and 35 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Stefan Brand <seiichiro@seiichiro0185.org>
|
* Copyright (c) 2014, Stefan Brand <seiichiro@seiichiro0185.org>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Stefan Brand <seiichiro@seiichiro0185.org>
|
* Copyright (c) 2014, Stefan Brand <seiichiro@seiichiro0185.org>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
@ -85,7 +85,7 @@ Page {
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
horizontalAlignment: TextEdit.Center
|
horizontalAlignment: TextEdit.Center
|
||||||
readOnly: true
|
readOnly: true
|
||||||
text: qsTr("SailOTP uses the following third party libs:")+"\n\nhttp://caligatio.github.io/jsSHA/\nhttps://github.com/mdp/gibberish-aes"
|
text: qsTr("SailOTP uses the following third party libs:")+"\n\nhttp://caligatio.github.io/jsSHA/\nhttps://github.com/mdp/gibberish-aes/\nhttp://sourceforge.net/projects/qzxing/"
|
||||||
color: "white"
|
color: "white"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Stefan Brand <seiichiro@seiichiro0185.org>
|
* Copyright (c) 2014, Stefan Brand <seiichiro@seiichiro0185.org>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Stefan Brand <seiichiro@seiichiro0185.org>
|
* Copyright (c) 2014, Stefan Brand <seiichiro@seiichiro0185.org>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
@ -84,6 +84,19 @@ Dialog {
|
||||||
id: exportFlickable
|
id: exportFlickable
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
PullDownMenu {
|
||||||
|
MenuItem {
|
||||||
|
text: mode == "export" ? qsTr("Import") : qsTr("Export")
|
||||||
|
onClicked: {
|
||||||
|
if (mode == "export") {
|
||||||
|
mode = "import"
|
||||||
|
} else {
|
||||||
|
mode = "export"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VerticalScrollDecorator {}
|
VerticalScrollDecorator {}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Stefan Brand <seiichiro@seiichiro0185.org>
|
* Copyright (c) 2014, Stefan Brand <seiichiro@seiichiro0185.org>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
@ -103,20 +103,11 @@ Page {
|
||||||
onClicked: pageStack.push(Qt.resolvedUrl("About.qml"))
|
onClicked: pageStack.push(Qt.resolvedUrl("About.qml"))
|
||||||
}
|
}
|
||||||
MenuItem {
|
MenuItem {
|
||||||
text: qsTr("Export Token-DB")
|
text: qsTr("Export / Import")
|
||||||
onClicked: pageStack.push(Qt.resolvedUrl("ExportPage.qml"), {parentPage: mainPage, mode: "export"})
|
onClicked: pageStack.push(Qt.resolvedUrl("ExportPage.qml"), {parentPage: mainPage, mode: "export"})
|
||||||
}
|
}
|
||||||
MenuItem {
|
|
||||||
text: qsTr("Import Token-DB")
|
|
||||||
onClicked: pageStack.push(Qt.resolvedUrl("ExportPage.qml"), {parentPage: mainPage, mode: "import"})
|
|
||||||
}
|
|
||||||
MenuItem {
|
MenuItem {
|
||||||
text: qsTr("Add Token")
|
text: qsTr("Add Token")
|
||||||
onClicked: pageStack.push(Qt.resolvedUrl("AddOTP.qml"), {parentPage: mainPage})
|
|
||||||
}
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("Scan Token")
|
|
||||||
onClicked: pageStack.push(Qt.resolvedUrl("ScanOTP.qml"), {parentPage: mainPage})
|
onClicked: pageStack.push(Qt.resolvedUrl("ScanOTP.qml"), {parentPage: mainPage})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Stefan Brand <seiichiro@seiichiro0185.org>
|
* Copyright (c) 2014, Stefan Brand <seiichiro@seiichiro0185.org>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
@ -32,6 +32,7 @@ import QtMultimedia 5.0
|
||||||
import Sailfish.Silica 1.0
|
import Sailfish.Silica 1.0
|
||||||
import Sailfish.Media 1.0 // Not allowed in harbour, but normal VideoOutput doesn't work yet!
|
import Sailfish.Media 1.0 // Not allowed in harbour, but normal VideoOutput doesn't work yet!
|
||||||
import harbour.sailotp.QZXing 2.2
|
import harbour.sailotp.QZXing 2.2
|
||||||
|
import harbour.sailotp.FileIO 1.0
|
||||||
import "../lib/urldecoder.js" as URL
|
import "../lib/urldecoder.js" as URL
|
||||||
|
|
||||||
Page {
|
Page {
|
||||||
|
@ -39,9 +40,44 @@ Page {
|
||||||
|
|
||||||
property QtObject parentPage: null
|
property QtObject parentPage: null
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: scanTimer
|
||||||
|
interval: 100
|
||||||
|
running: false
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
if (fileIO.mkpath(XDG_CACHE_DIR)) {
|
||||||
|
busy.running = true
|
||||||
|
cam.imageCapture.captureToLocation(XDG_CACHE_DIR + "/qrscan.jpg");
|
||||||
|
} else {
|
||||||
|
notify.show(qsTr("Can't access temporary directory"), 3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SilicaFlickable {
|
SilicaFlickable {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
PullDownMenu {
|
||||||
|
MenuItem {
|
||||||
|
text: qsTr("Add manually")
|
||||||
|
onClicked: pageStack.replace(Qt.resolvedUrl("AddOTP.qml"), {parentPage: parentPage, paramNew: true})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PageHeader {
|
||||||
|
id: header
|
||||||
|
title: "Scan Code"
|
||||||
|
}
|
||||||
|
|
||||||
|
BusyIndicator {
|
||||||
|
id: busy
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 16
|
||||||
|
running: false
|
||||||
|
}
|
||||||
|
|
||||||
Camera {
|
Camera {
|
||||||
id: cam
|
id: cam
|
||||||
|
|
||||||
|
@ -51,24 +87,12 @@ Page {
|
||||||
|
|
||||||
imageCapture {
|
imageCapture {
|
||||||
onImageSaved: {
|
onImageSaved: {
|
||||||
decoder.decodeImageFromFile("/tmp/qrscan.jpg");
|
decoder.decodeImageFromFile(XDG_CACHE_DIR + "/qrscan.jpg");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GStreamerVideoOutput {
|
QZXing {
|
||||||
id: videoPreview
|
|
||||||
anchors.centerIn: parent
|
|
||||||
source: cam
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
cam.imageCapture.captureToLocation("/tmp/qrscan.jpg");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QZXing{
|
|
||||||
id: decoder
|
id: decoder
|
||||||
|
|
||||||
enabledDecoders: QZXing.DecoderFormat_QR_CODE
|
enabledDecoders: QZXing.DecoderFormat_QR_CODE
|
||||||
|
@ -77,14 +101,45 @@ Page {
|
||||||
onTagFound: {
|
onTagFound: {
|
||||||
console.log("Barcode data: " + tag)
|
console.log("Barcode data: " + tag)
|
||||||
var ret = URL.decode(tag);
|
var ret = URL.decode(tag);
|
||||||
if (ret.type != "" && ret.title != "" && ret.secret != "" && (ret.counter != "" || ret.type == "TOTP ")) {
|
busy.running = false
|
||||||
|
if (ret && ret.type != "" && ret.title != "" && ret.secret != "" && (ret.counter != "" || ret.type == "TOTP")) {
|
||||||
pageStack.replace(Qt.resolvedUrl("AddOTP.qml"), {parentPage: parentPage, paramLabel: ret.title, paramKey: ret.secret, paramType: ret.type, paramCounter: ret.counter, paramNew: true})
|
pageStack.replace(Qt.resolvedUrl("AddOTP.qml"), {parentPage: parentPage, paramLabel: ret.title, paramKey: ret.secret, paramType: ret.type, paramCounter: ret.counter, paramNew: true})
|
||||||
} else {
|
} else {
|
||||||
notify.show(qsTr("Error decoding QR-Code"), 3000);
|
notify.show(qsTr("No valid Token data found."), 3000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onDecodingFinished: console.log("Decoding finished " + (succeeded==true ? "successfully" : "unsuccessfully") )
|
onDecodingFinished: if (succeeded==false) scanTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
FileIO {
|
||||||
|
id: fileIO
|
||||||
|
}
|
||||||
|
|
||||||
|
GStreamerVideoOutput {
|
||||||
|
id: prev
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.top: header.bottom
|
||||||
|
source: cam
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: scanTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: text
|
||||||
|
|
||||||
|
anchors.top: prev.bottom
|
||||||
|
anchors.topMargin: 32
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
width: parent.width - 2*Theme.paddingLarge
|
||||||
|
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
maximumLineCount: 4
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.primaryColor
|
||||||
|
text: qsTr("Tap the picture to start scanning. Pull down to add Token manually.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, Stefan Brand <seiichiro@seiichiro0185.org>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
* materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. The names of the contributors may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QDir>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
|
|
||||||
FileIO::FileIO(QObject *parent) :
|
FileIO::FileIO(QObject *parent) :
|
||||||
|
@ -71,3 +101,13 @@ bool FileIO::exists(const QString& filename)
|
||||||
QFile file(filename);
|
QFile file(filename);
|
||||||
return file.exists();
|
return file.exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FileIO::mkpath(const QString& dirpath) {
|
||||||
|
if (dirpath.isEmpty()) {
|
||||||
|
emit error("Source is empty!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDir dir(dirpath);
|
||||||
|
return dir.mkpath(dirpath);
|
||||||
|
}
|
||||||
|
|
30
src/fileio.h
30
src/fileio.h
|
@ -1,3 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, Stefan Brand <seiichiro@seiichiro0185.org>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
* materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. The names of the contributors may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef FILEIO_H
|
#ifndef FILEIO_H
|
||||||
#define FILEIO_H
|
#define FILEIO_H
|
||||||
|
|
||||||
|
@ -18,6 +47,7 @@ public:
|
||||||
Q_INVOKABLE bool write(const QString& data);
|
Q_INVOKABLE bool write(const QString& data);
|
||||||
Q_INVOKABLE bool exists();
|
Q_INVOKABLE bool exists();
|
||||||
Q_INVOKABLE bool exists(const QString& filename);
|
Q_INVOKABLE bool exists(const QString& filename);
|
||||||
|
Q_INVOKABLE bool mkpath(const QString& dirpath);
|
||||||
|
|
||||||
QString source() { return mSource; };
|
QString source() { return mSource; };
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Stefan Brand <seiichiro@seiichiro0185.org>
|
* Copyright (c) 2014, Stefan Brand <seiichiro@seiichiro0185.org>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
@ -61,6 +61,7 @@ int main(int argc, char *argv[])
|
||||||
// Prepare the QML and set Homedir
|
// Prepare the QML and set Homedir
|
||||||
view->setSource(SailfishApp::pathTo("qml/harbour-sailotp.qml"));
|
view->setSource(SailfishApp::pathTo("qml/harbour-sailotp.qml"));
|
||||||
view->rootContext()->setContextProperty("XDG_HOME_DIR", QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
|
view->rootContext()->setContextProperty("XDG_HOME_DIR", QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
|
||||||
|
view->rootContext()->setContextProperty("XDG_CACHE_DIR", QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
|
||||||
view->show();
|
view->show();
|
||||||
|
|
||||||
// Run the app
|
// Run the app
|
||||||
|
|
Loading…
Reference in a new issue