Skip to content
This repository has been archived by the owner on Oct 19, 2022. It is now read-only.

Commit

Permalink
Import from images
Browse files Browse the repository at this point in the history
  • Loading branch information
Levminer committed Jul 15, 2022
1 parent f7177cc commit c6668a1
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 3 deletions.
7 changes: 4 additions & 3 deletions interface/windows/import/import.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<h3>Choose images that contain a 2FA QR code.</h3>
</div>
<div class="ml-10 flex gap-3">
<button class="button requirePassword">
<button class="button requirePassword" on:click={chooseImages}>
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<line x1="15" y1="8" x2="15.01" y2="8" />
Expand Down Expand Up @@ -120,16 +120,17 @@

<script>
import { onDestroy } from "svelte"
import { chooseImages } from "./index"
import Details from "../../components/details.svelte"
import { state } from "../../stores/state"
const stateSubscriber = state.subscribe((value) => {
/* const stateSubscriber = state.subscribe((value) => {
console.log(value)
})
state.set({ importData: "asd" })
onDestroy(() => {
stateSubscriber()
})
}) */
</script>
61 changes: 61 additions & 0 deletions interface/windows/import/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import QrcodeDecoder from "qrcode-decoder"
import { fs, dialog } from "@tauri-apps/api"
import { state } from "../../stores/state"
import { totpImageConverter, migrationImageConverter } from "../../../libraries/convert"
import { navigate } from "../../../libraries/navigate"

export const chooseImages = async () => {
const filePaths = await dialog.open({ multiple: true, filters: [{ name: "Image file", extensions: ["jpg", "jpeg", "png", "bmp"] }] })

if (filePaths === null) {
return
}

const images: string[] = []

for (let i = 0; i < filePaths.length; i++) {
const file = await fs.readBinaryFile(filePaths[i])

const blob = new Blob([file], { type: "application/octet-binary" })
const url = URL.createObjectURL(blob)

images.push(url)
}

let string = ""

for (let i = 0; i < images.length; i++) {
const processImages = async () => {
const qr = new QrcodeDecoder()

// decode image
const res = await qr.decodeFromImage(images[i])

if (res === false) {
// no qr code found
// return invoke("error", { invokeMessage: "No QR code found on the picture!\n\nPlease try again with another picture!" })
} else if (res.data.startsWith("otpauth://totp/") || res.data.startsWith("otpauth-migration://")) {
if (res.data.startsWith("otpauth://totp/")) {
string += totpImageConverter(res.data)
} else {
string += migrationImageConverter(res.data)
}

if (images.length === i + 1) {
// invoke("info", { invokeMessage: "QR code(s) found!" })

console.log(string)

state.set({ importData: string })

navigate("/codes")
}
} else {
// no qr code found
// return invoke("error", { invokeMessage: "Wrong QR code found on the picture!\n\nPlease try again with another picture!" })
}
}

processImages()
}
}
56 changes: 56 additions & 0 deletions libraries/convert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,59 @@ export const textConverter = (text: string, sortNumber: number): LibImportFile =
types,
}
}

/**
* Convert TOTP QR code pictures to string
* @param {string} data
* @return {string} string
*/
export const totpImageConverter = (data: string): string => {
// get url
let url = data.replaceAll(/\s/g, "")
url = url.slice(15)

// get name
const nameIndex = url.match(/[?]/)
const name = url.slice(0, nameIndex.index)
url = url.slice(name.length + 1)

// get secret
const secretIndex = url.match(/[&]/)
const secret = url.slice(7, secretIndex.index)
url = url.slice(secret.length + 14 + 1)

// get issuer
let issuer = url

// check if issuer is empty
if (issuer === "") {
issuer = name
}

// add to final string
return `\nName: ${name} \nSecret: ${secret} \nIssuer: ${issuer} \nType: OTP_TOTP\n`
}

/**
* Convert Migration QR code pictures to string
* @param {string} data
* @return {string} string
*/
export const migrationImageConverter = (data: string): string => {
// return string
let returnString = ""

// split string
const uri = data.split("=")

// decode data
const decoded = googleAuthenticatorConverter(uri[1])

// make a string
decoded.forEach((element) => {
const tempString = `\nName: ${element.name} \nSecret: ${element.secret} \nIssuer: ${element.issuer} \nType: OTP_TOTP\n`
returnString += tempString
})

return returnString
}
5 changes: 5 additions & 0 deletions libraries/navigate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { router } from "tinro"

export const navigate = (link: string) => {
router.goto(link)
}
27 changes: 27 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"@rgossiaux/svelte-headlessui": "^1.0.2",
"otpauth": "^8.0.1",
"protocol-buffers": "^5.0.0",
"qrcode-decoder": "^0.2.2",
"svelte": "^3.49.0"
}
}

0 comments on commit c6668a1

Please sign in to comment.