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

Commit

Permalink
Webcam import, import style fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Levminer committed Aug 26, 2022
1 parent 7a9d540 commit cc1398d
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 9 deletions.
18 changes: 9 additions & 9 deletions interface/windows/import/import.svelte
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<div class="transparent-900 m-auto my-20 w-4/5 rounded-2xl p-10 text-left">
<h1 class="px-10">Supported QR codes</h1>
<div class="mx-auto flex flex-col items-center justify-center rounded-2xl p-10">
<div class="transparent-800 mb-5 flex w-full flex-row items-center justify-between rounded-xl p-5 text-left">
<div class="transparent-800 mb-5 flex w-full flex-row items-center justify-between rounded-xl p-5 text-left sm:flex-wrap">
<div>
<h2>TOTP 2FA QR code</h2>
<h3>A TOTP QR code is that you find mostly everywhere, if you want to setup 2FA. Consist of 6 digits which are changing every 30 seconds.</h3>
</div>
<div class="ml-20 flex gap-3">
<button class="button requirePassword">
<div class="ml-20 flex gap-3 sm:ml-0 sm:mt-5">
<button class="button">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
Expand All @@ -16,13 +16,13 @@
</div>
</div>

<div class="transparent-800 flex w-full flex-row items-center justify-between rounded-xl p-5 text-left">
<div class="transparent-800 flex w-full flex-row items-center justify-between rounded-xl p-5 text-left sm:flex-wrap">
<div>
<h2>Google Authenticator QR code</h2>
<h3>A Google Authenticator code is what you can export, and contains all of your already imported codes.</h3>
</div>
<div class="ml-20 flex gap-3">
<button class="button requirePassword">
<div class="ml-20 flex gap-3 sm:ml-0 sm:mt-5">
<button class="button">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
Expand All @@ -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" on:click={chooseImages}>
<button class="button" 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 @@ -85,7 +85,7 @@
<h5>Use your webcam to scan a 2FA QR code.</h5>
</div>
<div>
<button class="smallButton">
<button class="smallButton" on:click={useWebcam}>
<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" />
<circle cx="12" cy="10" r="7" />
Expand Down Expand Up @@ -187,6 +187,6 @@
</dialog>

<script>
import { captureScreen, chooseFile, chooseImages, manualEntry, showManualEntry } from "./index"
import { captureScreen, chooseFile, chooseImages, manualEntry, showManualEntry, useWebcam } from "./index"
import Details from "../../components/details.svelte"
</script>
77 changes: 77 additions & 0 deletions interface/windows/import/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,80 @@ export const captureScreen = async () => {
dialog.message(`Error occurred during the screen capture: \n\n${err}`, { type: "error" })
}
}

/**
* Check for an available webcam
*/
const webcamAvailable = async () => {
const md = navigator.mediaDevices

if (!md || !md.enumerateDevices) {
return false
} else {
const devices = await md.enumerateDevices()

for (let i = 0; i < devices.length; i++) {
if (devices[i].kind === "videoinput") {
return true
}

if (i === devices.length - 1) {
return false
}
}
}
}

export const useWebcam = async () => {
const hasWebcam = await webcamAvailable()

if (hasWebcam === false) {
// Not found webcam
dialog.message("Not found webcam! \n\nPlease check if your webcam is working correctly or not used by another application.", { type: "error" })
} else {
const dialogElement: LibDialogElement = document.querySelector(".dialog1")
const videoElement: HTMLVideoElement = document.querySelector(".video")

dialogElement.showModal()

document.querySelector(".stopVideo").addEventListener("click", () => {
reader.stop()

dialogElement.close()
})

const reader = new QrcodeDecoder()

try {
const res = await reader.decodeFromCamera(videoElement)

let importString = ""

if (res.data.startsWith("otpauth://totp/") || res.data.startsWith("otpauth-migration://")) {
if (res.data.startsWith("otpauth://totp/")) {
importString += totpImageConverter(res.data)
} else {
importString += migrationImageConverter(res.data)
}

const state = getState()
state.importData += importString
setState(state)

reader.stop()

dialog.message("Codes imported. \n\nYou can edit your codes on the edit page.")

navigate("codes")
} else {
// Wrong QR code found
dialog.message("Wrong QR code found on the picture! \n\nPlease try again with another picture!", { type: "error" })
console.error("Wrong QR code found on the picture:", res)
}
} catch (err) {
// Unknown error
dialog.message(`Error occurred while using the webcam: \n\n${err}`, { type: "error" })
console.error(`Error during webcam import: ${err}`)
}
}
}

0 comments on commit cc1398d

Please sign in to comment.