Skip to content

Commit 5f5b096

Browse files
committed
Experimental import from screen #161
1 parent 5121a38 commit 5f5b096

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

app/import/src/js/screen.js

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
module.exports = {
2+
/**
3+
* Read QR code from screen capture
4+
*/
5+
captureFromScreen: () => {
6+
let string = ""
7+
8+
desktopCapturer.getSources({ types: ["screen"] }).then(async (sources) => {
9+
try {
10+
const stream = await navigator.mediaDevices.getUserMedia({
11+
audio: false,
12+
video: {
13+
mandatory: {
14+
chromeMediaSource: "desktop",
15+
chromeMediaSourceId: sources[0].id,
16+
minWidth: 1280,
17+
maxWidth: 1280,
18+
minHeight: 720,
19+
maxHeight: 720,
20+
},
21+
},
22+
})
23+
24+
qrHandleStream(stream)
25+
} catch (error) {
26+
dialog.showMessageBox(currentWindow, {
27+
title: "Authme",
28+
buttons: [lang.button.close],
29+
type: "error",
30+
noLink: true,
31+
message: `${lang.import_dialog.capture_error} \n\n${error}`,
32+
})
33+
34+
logger.error("Error starting capture!", error.stack)
35+
}
36+
})
37+
38+
const qrHandleStream = async (stream) => {
39+
const track = stream.getTracks()[0]
40+
41+
const video = document.querySelector("#qrVideo")
42+
video.style.display = "flex"
43+
video.srcObject = stream
44+
45+
const button = document.querySelector("#qrStop")
46+
button.style.display = "inline"
47+
48+
button.addEventListener("click", () => {
49+
video.style.display = "none"
50+
button.style.display = "none"
51+
52+
reader.stop()
53+
track.stop()
54+
})
55+
56+
const reader = new QrcodeDecoder()
57+
const res = await reader.decodeFromVideo(video)
58+
59+
if (res.data.startsWith("otpauth://totp/") || res.data.startsWith("otpauth-migration://")) {
60+
if (res.data.startsWith("otpauth://totp/")) {
61+
string += qrConvert(res.data)
62+
} else {
63+
string += gaConvert(res.data)
64+
}
65+
66+
const save_exists = fs.existsSync(path.join(folder_path, "codes", "codes.authme"))
67+
68+
if (save_exists === true) {
69+
await dialog.showMessageBox(currentWindow, {
70+
title: "Authme",
71+
buttons: [lang.button.close],
72+
type: "info",
73+
noLink: true,
74+
defaultId: 0,
75+
message: `${lang.import_dialog.correct_qrcode_found_0} ${lang.import_dialog.correct_qrcode_found_1}`,
76+
})
77+
78+
saveFile(string)
79+
} else {
80+
const result = await dialog.showMessageBox(currentWindow, {
81+
title: "Authme",
82+
buttons: [lang.button.yes, lang.button.no],
83+
type: "info",
84+
noLink: true,
85+
defaultId: 1,
86+
cancelId: 1,
87+
message: `${lang.import_dialog.correct_qrcode_found_2} ${lang.import_dialog.correct_qrcode_found_3}`,
88+
})
89+
90+
if (result.response === 1) {
91+
ipc.invoke("importedCodes", Buffer.from(string).toString("base64"))
92+
} else {
93+
ipc.invoke("importedCodes", Buffer.from(string).toString("base64"))
94+
95+
saveFile(string)
96+
}
97+
}
98+
} else if (res.data !== "") {
99+
dialog.showMessageBox(currentWindow, {
100+
title: "Authme",
101+
buttons: [lang.button.close],
102+
type: "error",
103+
noLink: true,
104+
message: lang.import_dialog.wrong_qrcode,
105+
})
106+
107+
return logger.error("Wrong QR code found (QR)")
108+
}
109+
110+
if (res.data !== "") {
111+
video.style.display = "none"
112+
button.style.display = "none"
113+
114+
reader.stop()
115+
track.stop()
116+
}
117+
}
118+
},
119+
}

0 commit comments

Comments
 (0)