Skip to content

Commit

Permalink
Initial 2FAS support #288
Browse files Browse the repository at this point in the history
  • Loading branch information
Levminer committed Feb 26, 2024
1 parent df7b932 commit 72f0c71
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 18 deletions.
3 changes: 2 additions & 1 deletion interface/utils/convert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ export const totpImageConverter = (data: string): string => {
url = url.slice(secret.length + 14 + 1)

// get issuer
let issuer = url
const issuerIndex = url.match(/[&]/)
let issuer = issuerIndex ? url.slice(0, issuerIndex.index) : url

// check if issuer is empty
if (issuer === "") {
Expand Down
17 changes: 13 additions & 4 deletions interface/utils/language/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ export const localeEN = {

import: {
supportedTypes: "Supported 2FA types",
totpQRCode: "TOTP QR code",
totpQRCode: "TOTP",
totpQRCodeText: "A TOTP QR code is what you find mostly everywhere, if you want to setup 2FA. Consist of 6 digits which are changing every 30 seconds.",
instructions: "Instructions",
googleAuthQRCode: "Google Authenticator QR code",
googleAuthQRCode: "Google Authenticator",
googleAuthQRCodeText: "If you are using Google Authenticator you can export all of your exiting codes and import them to Authme.",
chooseImportMethod: "Choose import method",
importFromImage: "Import from image",
Expand All @@ -92,9 +92,18 @@ export const localeEN = {
webcam: "Webcam",
webcamText: "Use your webcam to scan a compatible QR code.",
webcamButton: "Use webcam",
authmeFile: "Authme file",
authmeFileText: "Import all codes from an existing Authme import file.",
// authme
authme: "Authme",
authmeText: "Import all your codes from Authme.",
authmeFile: "Authme File",
authmeFileText: "Import all codes from an existing Authme import file you exported from Authme.",
authmeFileButton: "Choose file",
// 2FAS
twoFasAuth: "2FAS Authenticator",
twoFasAuthText: "Import all codes from from a 2FAS Authenticator backup.",
twoFasFile: "2FAS backup file (without password)",
twoFasFileText: "Import all codes from an existing 2FAS backup file without a password.",
twoFasFileButton: "Choose file",
// html dialogs
captureScreenTitle: "Capture screen import",
captureScreenWaiting: "Waiting for a QR code...",
Expand Down
19 changes: 14 additions & 5 deletions interface/utils/language/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ export const localeES: typeof localeEN = {

import: {
supportedTypes: "Tipos de 2FA admitidos",
totpQRCode: "Código QR TOTP",
totpQRCode: "TOTP",
totpQRCodeText: "Un código QR TOTP es lo que se encuentra principalmente en todas partes, si desea configurar 2FA. Consta de 6 dígitos que cambian cada 30 segundos.",
instructions: "Instrucciones",
googleAuthQRCode: "Código QR del autenticador de Google",
googleAuthQRCode: "Google Authenticator",
googleAuthQRCodeText: "Si está utilizando Google Authenticator, puede exportar todos sus códigos existentes e importarlos a Authme.",
chooseImportMethod: "Elija el método de importación",
importFromImage: "Importar desde imagen",
Expand All @@ -94,9 +94,18 @@ export const localeES: typeof localeEN = {
webcam: "Webcam",
webcamText: "use su Webcam para escanear un código QR 2FA.",
webcamButton: "Use webcam",
authmeFile: "Archivo de Authme",
authmeFileText: "Importe todos los códigos de un archivo de importación de Authme existente.",
authmeFileButton: "Elija el archivo",
// authme
authme: "Authme",
authmeText: "Import all your codes from Authme.",
authmeFile: "Authme File",
authmeFileText: "Import all codes from an existing Authme import file you exported from Authme.",
authmeFileButton: "Choose file",
// 2FAS
twoFasAuth: "2FAS Authenticator",
twoFasAuthText: "Import all codes from from a 2FAS Authenticator backup.",
twoFasFile: "2FAS backup file (without password)",
twoFasFileText: "Import all codes from an existing 2FAS backup file without a password.",
twoFasFileButton: "Choose file",
// html dialogs
captureScreenTitle: "Importación de pantalla de captura",
captureScreenWaiting: "Esperando un código QR...",
Expand Down
19 changes: 14 additions & 5 deletions interface/utils/language/hu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ export const localeHU: typeof localeEN = {

import: {
supportedTypes: "Támogatott 2FA típusok",
totpQRCode: "TOTP QR kód",
totpQRCode: "TOTP",
totpQRCodeText: "A TOTP QR kódokat találod mindenhol, ha 2FA-t akarsz beállítani. 6 számjegyből áll, amik 30 másodpercenként változnak.",
instructions: "Útmutató",
googleAuthQRCode: "Google Hitelesítő QR kód",
googleAuthQRCode: "Google Hitelesítő",
googleAuthQRCodeText: "Ha a Google Hitelesítőt használod, akkor exportálhatod a kódjaidat és importálhatod az Authme-be.",
chooseImportMethod: "Importálási mód kiválasztása",
importFromImage: "Importálás képről",
Expand All @@ -94,9 +94,18 @@ export const localeHU: typeof localeEN = {
webcam: "Webkamera",
webcamText: "Használd a webkamerádat egy 2FA QR kód beolvasásához.",
webcamButton: "Webkamera",
authmeFile: "Authme fájl",
authmeFileText: "Importálj be minden kódot egy Authme import fájlból.",
authmeFileButton: "Fájl kiválasztása",
// authme
authme: "Authme",
authmeText: "Import all your codes from Authme.",
authmeFile: "Authme File",
authmeFileText: "Import all codes from an existing Authme import file you exported from Authme.",
authmeFileButton: "Choose file",
// 2FAS
twoFasAuth: "2FAS Authenticator",
twoFasAuthText: "Import all codes from from a 2FAS Authenticator backup.",
twoFasFile: "2FAS backup file (without password)",
twoFasFileText: "Import all codes from an existing 2FAS backup file without a password.",
twoFasFileButton: "Choose file",
// translate dialogs
captureScreenTitle: "Képernyőről importálás",
captureScreenWaiting: "Várakozás a QR kódra...",
Expand Down
35 changes: 32 additions & 3 deletions interface/windows/import/import.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,37 @@

<div class="transparent-800 flex w-full flex-col items-start rounded-xl p-5 text-left">
<div>
<h2>{language.import.authmeFile}</h2>
<h3>{language.import.authmeFileText}</h3>
<h2>{language.import.twoFasAuth}</h2>
<h3>{language.import.twoFasAuthText}</h3>
</div>
<div class="mt-5 flex w-full">
<button class="button" on:click={showAuthmeFileDialog}>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /><line x1="12" y1="16" x2="12" y2="12" /><line x1="12" y1="8" x2="12.01" y2="8" /></svg>
{language.import.instructions}
</button>
</div>
<div class="mt-5 flex w-full">
<Details title={language.import.chooseImportMethod}>
<div class="flex flex-row justify-between">
<div>
<h4 class="text-white">{language.import.twoFasFile}</h4>
<h5>{language.import.twoFasFileText}</h5>
</div>
<div>
<button class="smallButton" on:click={twoFasAuthFile}>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 22h14a2 2 0 0 0 2-2V7.5L14.5 2H6a2 2 0 0 0-2 2v3" /><polyline points="14 2 14 8 20 8" /><path d="M5 17a3 3 0 1 0 0-6 3 3 0 0 0 0 6z" /><path d="m9 18-1.5-1.5" /></svg>
{language.import.authmeFileButton}
</button>
</div>
</div>
</Details>
</div>
</div>

<div class="transparent-800 flex w-full flex-col items-start rounded-xl p-5 text-left">
<div>
<h2>{language.import.authme}</h2>
<h3>{language.import.authmeText}</h3>
</div>
<div class="mt-5 flex w-full">
<button class="button" on:click={showAuthmeFileDialog}>
Expand Down Expand Up @@ -267,7 +296,7 @@
</dialog>

<script>
import { captureScreen, chooseFile, chooseImages, manualEntry, showAuthmeFileDialog, showGADialog, showManualEntry, showTOTPDialog, useWebcam } from "./index"
import { captureScreen, chooseFile, chooseImages, manualEntry, showAuthmeFileDialog, showGADialog, showManualEntry, showTOTPDialog, twoFasAuthFile, useWebcam } from "./index"
import Details from "../../components/details.svelte"
import { getLanguage } from "@utils/language"
Expand Down
36 changes: 36 additions & 0 deletions interface/windows/import/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,42 @@ export const chooseFile = async () => {
}
}

export const twoFasAuthFile = async () => {
const filePath = await dialog.open({ filters: [{ name: "2FAS file", extensions: ["2fas"] }] })

interface TwoFasFile {
services: {
otp: {
link: string
tokenType: string
}
}[]
}

if (filePath !== null) {
const loadedFile = await fs.readTextFile(filePath.toString())
const file: TwoFasFile = JSON.parse(loadedFile)
let importString = ""

for (let i = 0; i < file.services.length; i++) {
const service = file.services[i]

console.log(service)

if (service.otp.tokenType === "TOTP") {
importString += totpImageConverter(service.otp.link)
}
}

dialog.message(language.codes.dialog.codesImported)

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

navigate("codes")
}
}
/**
* Start a video capture, when a QR code detected try to read it
*/
Expand Down

0 comments on commit 72f0c71

Please sign in to comment.