diff --git a/README.md b/README.md index 985fd399..f8d60e7a 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,16 @@ # Authme -- A simple 2FA app for desktop built with Electron and Node.js. +- A simple 2FA cross platform app for desktop built with Electron and Node.js. # How to use -- Check out `extract/README.md` +- For technical people: Check out `extract/README.md` +- For simple people: Instructions in the app -# Build +# Development -`electron-packager . Authme --overwrite --platform=all --arch=x64 --icon=img/icon.icns --out=build` - -# NPM Pacages used - -### Dev - -- electron -- electron-packager - -### Main - -- bcrypt -- create-desktop-shortcuts -- cryptr -- speakeasy +- Start `npm run start` +- Build `npm run build` # License diff --git a/app/application/index.html b/app/application/index.html index 939baf84..078440cc 100644 --- a/app/application/index.html +++ b/app/application/index.html @@ -23,6 +23,16 @@

Here are your 2FA codes:


+
+ diff --git a/app/application/src/css/index.css b/app/application/src/css/index.css index a604b79a..7cc81ea2 100644 --- a/app/application/src/css/index.css +++ b/app/application/src/css/index.css @@ -1,6 +1,7 @@ body { background: rgb(0, 0, 0); background: linear-gradient(90deg, rgba(0, 0, 0, 1) 30%, rgba(42, 36, 36, 1) 100%); + overflow-y: scroll; } .center { @@ -125,31 +126,44 @@ body { font-size: 1.3rem; } -#grid0, -#grid1, -#grid2, -#grid3, -#grid4, -#grid5, -#grid6, -#grid7, -#grid8, -#grid9, -#grid10, -#grid11, -#grid12, -#grid13, -#grid14, -#grid15, -#grid16, -#grid17, -#grid18, -#grid19 { +.input2 { + width: 300px; + margin: 0 auto; + color: rgb(0, 0, 0); + background-color: white; + border-color: white; + font-size: 1rem; + padding: 15px 30px; + border-radius: 30px; + cursor: text; + text-align: center; + transition: 0.2s ease-in; + margin-bottom: 50px; display: none; } +.input2:hover { + background-color: var(--df_gray); + color: white; + border-color: white; +} + +.input2::placeholder { + color: black; +} + #save { display: unset; visibility: hidden; margin-bottom: 20px; } + +input:focus::placeholder { + transition: 0.2s ease-in; + color: transparent; +} + +input:hover::placeholder { + transition: 0.2s ease-in; + color: transparent; +} diff --git a/app/application/src/js/index.js b/app/application/src/js/index.js index 4f4ac852..e3f9680e 100644 --- a/app/application/src/js/index.js +++ b/app/application/src/js/index.js @@ -47,6 +47,7 @@ let separation = () => { let go = () => { document.querySelector("#title").textContent = "Here are your 2FA codes" + document.querySelector("#search").style.display = "grid" let generate = () => { // counter @@ -133,5 +134,47 @@ let go = () => { } else { document.querySelector("#input").style.display = "none" document.querySelector("#save").style.display = "none" + document.querySelector("#search").style.display = "grid" + } +} + +//? search +let search = () => { + const querry = [] + let search = document.querySelector("#search") + let input = search.value.toLowerCase() + let i = 0 + + // restart + for (let i = 0; i < names.length; i++) { + let div = document.querySelector(`#grid${[i]}`) + div.style.display = "grid" + } + + // get names + for (let i = 0; i < names.length; i++) { + let name = document.querySelector(`#name${[i]}`) + + querry.push(name.textContent.toLowerCase().trim()) + } + + // search + console.log(input) + querry.forEach((e) => { + if (e.startsWith(input)) { + console.log("found") + } else { + let div = document.querySelector(`#grid${[i]}`) + div.style.display = "none" + } + i++ + }) + + // if search empty + if (search.value == "") { + for (let i = 0; i < names.length; i++) { + let div = document.querySelector(`#grid${[i]}`) + div.style.display = "grid" + } } } diff --git a/app/application/src/js/save.js b/app/application/src/js/save.js index 107b2bdf..77cfbf41 100644 --- a/app/application/src/js/save.js +++ b/app/application/src/js/save.js @@ -11,7 +11,8 @@ fs.readFile(path.join(file_path, "hash.md"), "utf-8", (err, content) => { if (err) { console.log("The hash.md fle dont exist!") - document.querySelector("#title").textContent = "Please choose your exported file" + document.querySelector("#title").textContent = + "Please choose your exported file, if you don't have one: Go to the top menu > Advanced > Import" } else { prev = true diff --git a/app/export/index.html b/app/export/index.html new file mode 100644 index 00000000..0c63a827 --- /dev/null +++ b/app/export/index.html @@ -0,0 +1,28 @@ + + + + + Authme + + + + + + + + + + +
+

Authme

+

Export

+

You can export everything form your saved config.

+ +

Export

+

If you saved your config you can export the secrects and the QR codes.

+ +
+ +
+ + diff --git a/app/export/src/css/index.css b/app/export/src/css/index.css new file mode 100644 index 00000000..351531e7 --- /dev/null +++ b/app/export/src/css/index.css @@ -0,0 +1,90 @@ +body { + background: rgb(0, 0, 0); + background: linear-gradient(90deg, rgba(0, 0, 0, 1) 30%, rgba(42, 36, 36, 1) 100%); +} + +.center { + top: -50px; + width: 1000px; + height: auto; + padding-bottom: 50px; +} + +.button1 { + color: black; + background-color: white; + border-color: white; +} + +.button1:hover { + color: white; + border-color: white; +} + +.input1 { + color: black; + background-color: white; + border-color: white; + width: 250px; +} + +.input1:hover { + color: white; + border-color: white; +} + +#password_input2 { + position: relative; + top: 20px; +} + +#password_label2 { + position: relative; + top: 20px; +} + +#button1 { + position: relative; + top: 45px; +} + +.link1 { + font-size: 1rem !important; + position: relative; + top: 50px; + color: white !important; +} + +#result { + position: relative; + top: 50px; + margin: 0 auto; + border: 1px solid rgb(0, 0, 0); + padding: 1rem; + border-radius: 28px; + width: 550px; + height: 250px; + transition: 0.3s; + background-color: rgb(0, 0, 0); + color: rgb(255, 255, 255); + font-family: Arial, Helvetica, sans-serif; + font-size: 20px; + margin-bottom: 100px; + display: none; +} + +#result::-webkit-scrollbar { + width: 0px; + background: transparent; /* make scrollbar transparent */ +} + +.qr { + padding-top: 250px; + background-color: black; + margin-top: 50px; + border-radius: 30px; + margin: 0 auto; + margin-top: 20px; + width: 600px; + height: 500px; +} diff --git a/app/export/src/js/convert.js b/app/export/src/js/convert.js new file mode 100644 index 00000000..47bcdb6d --- /dev/null +++ b/app/export/src/js/convert.js @@ -0,0 +1,61 @@ +let data = [] +let save_text + +const handlefiles = (files) => { + // read file + if (window.FileReader) { + getastext(files[0]) + console.log("File uploaded successfully!") + /* state = 1 */ + } else { + console.log("Can't upload file!") + } +} + +const getastext = (fileToRead) => { + const reader = new FileReader() + reader.onload = loadhandler + reader.onerror = errorhandler + reader.readAsText(fileToRead) +} + +const loadhandler = (event) => { + const text = event.target.result + console.log(text) + save_text = text + console.log(save_text) + processdata(text) +} + +const errorhandler = (evt) => { + if (evt.target.error.name == "NotReadableError") { + alert("Failed to upload the file! You uploaded a corrupted or not supported file!") + } +} + +const processdata = (text) => { + // remove double qoutes + const pre_data1 = text.replace(/"/g, "") + + // new line + const pre_data2 = pre_data1.replace(/,/g, "\n") + + // make the array + const pre_data3 = pre_data2.split(/\n/) + while (pre_data3.length) { + data.push(pre_data3.shift()) + } + + // remove first blank + data.splice(0, 1) + + data = data.filter((_, i) => { + return (i + 1) % 5 + }) + + console.log("Data:") + console.log(data.length) + console.log(data) + + separation() +} diff --git a/app/export/src/js/index.js b/app/export/src/js/index.js new file mode 100644 index 00000000..bcaccf9d --- /dev/null +++ b/app/export/src/js/index.js @@ -0,0 +1,103 @@ +const { ipcMain } = require("electron") +const fs = require("fs") +const electron = require("electron") +const ipc = electron.ipcRenderer +const path = require("path") +const Cryptr = require("cryptr") +const cryptr = new Cryptr("-3Lu)g%#11h7FpM?") +const qrcode = require("qrcode") + +const file_path = path.join(process.env.APPDATA, "/Levminer/Authme") + +let names = [] +let secret = [] +let issuer = [] +let type = [] + +let exp = () => { + fs.readFile(path.join(file_path, "hash.md"), "utf-8", (err, content) => { + if (err) { + console.log("The hash.md fle dont exist!") + } else { + let decrypted = cryptr.decrypt(content) + + console.log(decrypted) + + let result = document.querySelector("#result") + result.value = decrypted + result.style.display = "flex" + + processdata(decrypted) + } + }) +} + +let separation = () => { + document.querySelector("#but0").style.display = "none" + + let c0 = 0 + let c1 = 1 + let c2 = 2 + let c3 = 3 + + for (let i = 0; i < data.length; i++) { + if (i == c0) { + names.push(data[i]) + c0 = c0 + 4 + } + + if (i == c1) { + let secret_before = data[i] + let secret_after = secret_before.slice(8) + secret.push(secret_after) + c1 = c1 + 4 + } + + if (i == c2) { + let issuer_before = data[i] + let issuer_after = issuer_before.slice(8) + issuer.push(issuer_after) + c2 = c2 + 4 + } + + if (i == c3) { + type.push(data[i]) + c3 = c3 + 4 + } + } + + console.log(names) + console.log(secret) + console.log(issuer) + console.log(type) + + go() +} + +let go = () => { + for (let i = 0; i < names.length; i++) { + // create div + let element = document.createElement("div") + + qrcode.toDataURL(`otpauth://totp/${issuer[i]}?secret=${secret[i]}`, (err, data) => { + qr_data = data + + element.innerHTML = ` +
+ +

${issuer[i]}

+
` + }) + + // set div elements + + // set div in html + document.querySelector(".center").appendChild(element) + + // add one to counter + } +} + +let hide = () => { + ipc.send("hide2") +} diff --git a/app/import/index.html b/app/import/index.html new file mode 100644 index 00000000..02c7920c --- /dev/null +++ b/app/import/index.html @@ -0,0 +1,92 @@ + + + + + Authme + + + + + + + + + +
+

Authme

+

Import

+

You can import from Google Authenticator here.

+ + +

Instructions

+

+ Step 1 +
+
+ Export the QR codes from the Google Authenticato app: +
+ Tap on the three dots on the top right of the screen > Transfer Accounts > Export Accounts +
+
+ Step 2 +
+
+ Option 1: Import from QR code +
+ Save the two or one QR code with a screenshot or take a picture of them from another phone. Then transfer them to your computer. +
+
+ Option 2: Import from text +
+ Get 3rd party QR code reader from your application store. Scan the two or one QR code and then copy the text thats outputed, and then + send them to your computer. +
+
+ Step 3 +
+
+ Option 1: Import from QR code +
+ On your tray a folder will open, place your image(s) in the folder. If your image(s) not in .jpg then convert them to .jpg (just + google "image converter"). +
+ Rename your picture(s) to "pic0" and if you have one more then rename it to "pic1" (without quotation mark). +
+
+ Option 2: Import from text +
+ Scroll down, you will see two input fields. +
+ Paste your text from the QR code, if you have one more QR code then use the second input field. +
+
+ Step 4 +
+
+ Your file should be ready in your Authme folder. Go back to the main page: +
+ Top menu > Advanced > Import +
+ Click on the Choose file button, select your "exported.txt" file in your Authme folder. +
+
+ Step 5 +
+
+ AFTER YOU DONE DELETE "output.txt" AND "exported.txt" FROM YOUR AUTHME FOLDER. +

+ +

Choose option

+ + + +
+

Input codes

+ + +
+ +
+
+ + diff --git a/app/import/src/css/index.css b/app/import/src/css/index.css new file mode 100644 index 00000000..e069e9d7 --- /dev/null +++ b/app/import/src/css/index.css @@ -0,0 +1,98 @@ +body { + background: rgb(0, 0, 0); + background: linear-gradient(90deg, rgba(0, 0, 0, 1) 30%, rgba(42, 36, 36, 1) 100%); +} + +.center { + top: -50px; + width: 1000px; + height: auto; +} + +.button1 { + color: black; + background-color: white; + border-color: white; + margin-bottom: 30px; +} + +.button1:hover { + color: white; + border-color: white; +} + +.input1 { + color: black; + background-color: white; + border-color: white; + width: 250px; +} + +.input1:hover { + color: white; + border-color: white; +} + +.input1::placeholder { + color: black; +} + +#password_input2 { + position: relative; + top: 20px; +} + +#password_label2 { + position: relative; + top: 20px; +} + +#button1 { + position: relative; + top: 45px; +} + +#version { + position: relative; + top: 30px; +} + +.link1 { + font-size: 1rem !important; + position: relative; + top: 50px; + color: white !important; +} + +.grid { + display: grid; + grid-template-columns: repeat(5, 1fr); + grid-template-rows: repeat(5, 1fr); + grid-column-gap: 0px; + grid-row-gap: 0px; + + width: 300px; + background-color: black; + margin: 0 auto; +} + +input:focus::placeholder { + transition: 0.2s ease-in; + color: transparent; +} + +input:hover::placeholder { + transition: 0.2s ease-in; + color: transparent; +} + +.text-inputs { + display: none; + margin: 0 auto; + margin-top: 30px; +} + +#but2 { + margin-top: 15px; + margin-bottom: 30px; +} diff --git a/app/import/src/js/index.js b/app/import/src/js/index.js new file mode 100644 index 00000000..155cafa0 --- /dev/null +++ b/app/import/src/js/index.js @@ -0,0 +1,171 @@ +const { ipcMain, shell } = require("electron") +const fs = require("fs") +const electron = require("electron") +const ipc = electron.ipcRenderer +const path = require("path") +const QrCode = require("qrcode-reader") +const Jimp = require("jimp") + +let file_path = path.join(__dirname, "src/py/extract_2fa_secret.py") +let counter = 0 + +//? import from qr code +let import_qrcode = () => { + let full_folder = path.join(__dirname, "/img/place_your_images_inside_this_folder") + let folder = path.join(__dirname, "/img/") + + // create img folder + if (!fs.existsSync(folder)) { + fs.mkdirSync(folder) + } + + // create place folder + if (!fs.existsSync(full_folder)) { + fs.mkdirSync(full_folder) + } + + // open folder + if (counter == 0) { + shell.showItemInFolder(full_folder) + document.querySelector("#choose").textContent = "Folder opened, place the images in the folder" + document.querySelector("#but0").textContent = "Convert" + document.querySelector("#but1").style.display = "none" + } + + if (counter == 1) { + let buffer0 + let buffer1 + + //! TRY FIRST PIC + try { + buffer0 = fs.readFileSync(path.join(full_folder, "pic0.jpg"), (err) => { + if (err) { + return console.log("NO PIC0.jpg") + } + + return console.log("FOUND PIC0.jpg") + }) + } catch (err) { + document.querySelector("#but0").textContent = "Error, no picture found" + return console.log("ESCAPED PIC0.jpg") + } + + //! FIRST PIC + Jimp.read(buffer0, (err, image) => { + if (err) { + console.error(err) + } + + let qr = new QrCode() + + qr.callback = (err, value) => { + if (err) { + console.error(err) + document.querySelector("#but0").textContent = "Error, no QR code on the picture" + } + + fs.writeFile("output.txt", value.result, (err) => { + if (err) { + document.querySelector("#but0").textContent = "Error, no picture found" + console.log("Output don't created!") + } else { + document.querySelector("#but0").textContent = "File created" + console.log("Output started file created!") + } + }) + } + + qr.decode(image.bitmap) + }) + + //! TRY SECOND PIC + try { + buffer1 = fs.readFileSync(path.join(full_folder, "pic1.jpg"), (err) => { + if (err) { + return console.log("NO PIC1.jpg") + } + + return console.log("FOUND PIC1.jpg") + }) + } catch (err) { + generate() + return console.log("ESCAPED PIC1.jpg") + } + + //! SECOND PIC + Jimp.read(buffer1, (err, image) => { + if (err) { + console.error(err) + } + + let qr = new QrCode() + + qr.callback = (err, value) => { + if (err) { + console.error(err) + } + + fs.appendFile("output.txt", `\n${value.result}`, (err) => { + if (err) { + console.log("Output don't modified!") + } else { + console.log("Output modified") + } + }) + } + + qr.decode(image.bitmap) + }) + } + + if (counter == 1) { + setTimeout(() => { + let python = require("child_process").spawn("python", [file_path, "output.txt"]) + }, 1000) + } + counter++ +} + +let generate = () => { + setTimeout(() => { + let python = require("child_process").spawn("python", [file_path, "output.txt"]) + }, 1000) +} + +//? start input text +let import_text0 = () => { + let text_inputs = document.querySelector(".text-inputs") + text_inputs.style.display = "block" + + document.querySelector("#choose").style.display = "none" + document.querySelector("#but0").style.display = "none" + document.querySelector("#but1").style.display = "none" +} + +//? resume input text +let import_text1 = () => { + let input0 = document.querySelector("#input0").value + let input1 = document.querySelector("#input1").value + + if (input0 !== "") { + fs.writeFile("output.txt", `${input0} \n${input1}`, (err) => { + if (err) { + console.log("Output file don't created!") + document.querySelector("#but2").textContent = "Error, restart the app please" + } else { + console.log("Output file created!") + document.querySelector("#but2").textContent = "File created" + } + }) + + // convert + let python = require("child_process").spawn("python", [file_path, "output.txt"]) + } else { + document.querySelector("#but2").textContent = "Error, fill in at least the frist input" + } +} + +//? hide +let hide = () => { + ipc.send("hide1") +} diff --git a/app/import/src/py/extract_2fa_secret.py b/app/import/src/py/extract_2fa_secret.py new file mode 100644 index 00000000..c3be7c91 --- /dev/null +++ b/app/import/src/py/extract_2fa_secret.py @@ -0,0 +1,71 @@ +import argparse +import base64 +import fileinput +import sys +from urllib.parse import parse_qs, urlencode, urlparse + +import google_2fa_export + +arg_parser = argparse.ArgumentParser() +arg_parser.add_argument("--verbose", "-v", help="verbose output", action="store_true") +arg_parser.add_argument( + "--qr", "-q", help="print QR codes (otpauth://...)", action="store_true" +) +arg_parser.add_argument( + "infile", + help='file or - for stdin (default: -) with "otpauth-migration://..." URLs separated by newlines, lines starting with # are ignored', +) +args = arg_parser.parse_args() + +verbose = args.verbose + + +def get_enum_name_by_number(parent, field_name): + field_value = getattr(parent, field_name) + return ( + parent.DESCRIPTOR.fields_by_name[field_name] + .enum_type.values_by_number.get(field_value) + .name + ) + + +def convert_secret_from_bytes_to_base32_str(bytes): + return str(base64.b32encode(otp.secret), "utf-8").replace("=", "") + + +for line in (line.strip() for line in fileinput.input(args.infile)): + if verbose: + print(line) + if line.startswith("#"): + continue + parsed_url = urlparse(line) + params = parse_qs(parsed_url.query) + data_encoded = params["data"][0] + data = base64.b64decode(data_encoded) + payload = google_2fa_export.MigrationPayload() + payload.ParseFromString(data) + if verbose: + print(payload) + + # write to file + file = open("exported.txt", "a") + + for otp in payload.otp_parameters: + print("\nName: {}".format(otp.name)) + file.write("\nName: {} \n".format(otp.name)) + secret = convert_secret_from_bytes_to_base32_str(otp.secret) + print("Secret: {}".format(secret)) + file.write(("Secret: {} \n".format(secret))) + if otp.issuer: + print("Issuer: {}".format(otp.issuer)) + file.write("Issuer: {} \n".format(otp.issuer)) + print("Type: {}".format(get_enum_name_by_number(otp, "type"))) + file.write(("Type: {} \n".format(get_enum_name_by_number(otp, "type")))) + url_params = {"secret": secret} + if otp.type == 1: + url_params["counter"] = otp.counter + if otp.issuer: + url_params["issuer"] = otp.issuer + otp_url = "otpauth://{}/{}?".format( + "totp" if otp.type == 2 else "hotp", otp.name + ) + urlencode(url_params) diff --git a/app/import/src/py/google_2fa_export.py b/app/import/src/py/google_2fa_export.py new file mode 100644 index 00000000..7a1d10e7 --- /dev/null +++ b/app/import/src/py/google_2fa_export.py @@ -0,0 +1,408 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: google_auth.proto + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database + +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor.FileDescriptor( + name="google_auth.proto", + package="", + syntax="proto3", + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n\x11google_auth.proto"\xb7\x03\n\x10MigrationPayload\x12\x37\n\x0eotp_parameters\x18\x01 \x03(\x0b\x32\x1f.MigrationPayload.OtpParameters\x12\x0f\n\x07version\x18\x02 \x01(\x05\x12\x12\n\nbatch_size\x18\x03 \x01(\x05\x12\x13\n\x0b\x62\x61tch_index\x18\x04 \x01(\x05\x12\x10\n\x08\x62\x61tch_id\x18\x05 \x01(\x05\x1a\xb7\x01\n\rOtpParameters\x12\x0e\n\x06secret\x18\x01 \x01(\x0c\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06issuer\x18\x03 \x01(\t\x12.\n\talgorithm\x18\x04 \x01(\x0e\x32\x1b.MigrationPayload.Algorithm\x12\x0e\n\x06\x64igits\x18\x05 \x01(\x05\x12\'\n\x04type\x18\x06 \x01(\x0e\x32\x19.MigrationPayload.OtpType\x12\x0f\n\x07\x63ounter\x18\x07 \x01(\x03",\n\tAlgorithm\x12\x10\n\x0c\x41LGO_INVALID\x10\x00\x12\r\n\tALGO_SHA1\x10\x01"6\n\x07OtpType\x12\x0f\n\x0bOTP_INVALID\x10\x00\x12\x0c\n\x08OTP_HOTP\x10\x01\x12\x0c\n\x08OTP_TOTP\x10\x02\x62\x06proto3', +) + + +_MIGRATIONPAYLOAD_ALGORITHM = _descriptor.EnumDescriptor( + name="Algorithm", + full_name="MigrationPayload.Algorithm", + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name="ALGO_INVALID", + index=0, + number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.EnumValueDescriptor( + name="ALGO_SHA1", + index=1, + number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key, + ), + ], + containing_type=None, + serialized_options=None, + serialized_start=361, + serialized_end=405, +) +_sym_db.RegisterEnumDescriptor(_MIGRATIONPAYLOAD_ALGORITHM) + +_MIGRATIONPAYLOAD_OTPTYPE = _descriptor.EnumDescriptor( + name="OtpType", + full_name="MigrationPayload.OtpType", + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name="OTP_INVALID", + index=0, + number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.EnumValueDescriptor( + name="OTP_HOTP", + index=1, + number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.EnumValueDescriptor( + name="OTP_TOTP", + index=2, + number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key, + ), + ], + containing_type=None, + serialized_options=None, + serialized_start=407, + serialized_end=461, +) +_sym_db.RegisterEnumDescriptor(_MIGRATIONPAYLOAD_OTPTYPE) + + +_MIGRATIONPAYLOAD_OTPPARAMETERS = _descriptor.Descriptor( + name="OtpParameters", + full_name="MigrationPayload.OtpParameters", + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name="secret", + full_name="MigrationPayload.OtpParameters.secret", + index=0, + number=1, + type=12, + cpp_type=9, + label=1, + has_default_value=False, + default_value=b"", + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="name", + full_name="MigrationPayload.OtpParameters.name", + index=1, + number=2, + type=9, + cpp_type=9, + label=1, + has_default_value=False, + default_value=b"".decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="issuer", + full_name="MigrationPayload.OtpParameters.issuer", + index=2, + number=3, + type=9, + cpp_type=9, + label=1, + has_default_value=False, + default_value=b"".decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="algorithm", + full_name="MigrationPayload.OtpParameters.algorithm", + index=3, + number=4, + type=14, + cpp_type=8, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="digits", + full_name="MigrationPayload.OtpParameters.digits", + index=4, + number=5, + type=5, + cpp_type=1, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="type", + full_name="MigrationPayload.OtpParameters.type", + index=5, + number=6, + type=14, + cpp_type=8, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="counter", + full_name="MigrationPayload.OtpParameters.counter", + index=6, + number=7, + type=3, + cpp_type=2, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + ], + extensions=[], + nested_types=[], + enum_types=[], + serialized_options=None, + is_extendable=False, + syntax="proto3", + extension_ranges=[], + oneofs=[], + serialized_start=176, + serialized_end=359, +) + +_MIGRATIONPAYLOAD = _descriptor.Descriptor( + name="MigrationPayload", + full_name="MigrationPayload", + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name="otp_parameters", + full_name="MigrationPayload.otp_parameters", + index=0, + number=1, + type=11, + cpp_type=10, + label=3, + has_default_value=False, + default_value=[], + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="version", + full_name="MigrationPayload.version", + index=1, + number=2, + type=5, + cpp_type=1, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="batch_size", + full_name="MigrationPayload.batch_size", + index=2, + number=3, + type=5, + cpp_type=1, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="batch_index", + full_name="MigrationPayload.batch_index", + index=3, + number=4, + type=5, + cpp_type=1, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="batch_id", + full_name="MigrationPayload.batch_id", + index=4, + number=5, + type=5, + cpp_type=1, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + ], + extensions=[], + nested_types=[ + _MIGRATIONPAYLOAD_OTPPARAMETERS, + ], + enum_types=[ + _MIGRATIONPAYLOAD_ALGORITHM, + _MIGRATIONPAYLOAD_OTPTYPE, + ], + serialized_options=None, + is_extendable=False, + syntax="proto3", + extension_ranges=[], + oneofs=[], + serialized_start=22, + serialized_end=461, +) + +_MIGRATIONPAYLOAD_OTPPARAMETERS.fields_by_name[ + "algorithm" +].enum_type = _MIGRATIONPAYLOAD_ALGORITHM +_MIGRATIONPAYLOAD_OTPPARAMETERS.fields_by_name[ + "type" +].enum_type = _MIGRATIONPAYLOAD_OTPTYPE +_MIGRATIONPAYLOAD_OTPPARAMETERS.containing_type = _MIGRATIONPAYLOAD +_MIGRATIONPAYLOAD.fields_by_name[ + "otp_parameters" +].message_type = _MIGRATIONPAYLOAD_OTPPARAMETERS +_MIGRATIONPAYLOAD_ALGORITHM.containing_type = _MIGRATIONPAYLOAD +_MIGRATIONPAYLOAD_OTPTYPE.containing_type = _MIGRATIONPAYLOAD +DESCRIPTOR.message_types_by_name["MigrationPayload"] = _MIGRATIONPAYLOAD +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +MigrationPayload = _reflection.GeneratedProtocolMessageType( + "MigrationPayload", + (_message.Message,), + { + "OtpParameters": _reflection.GeneratedProtocolMessageType( + "OtpParameters", + (_message.Message,), + { + "DESCRIPTOR": _MIGRATIONPAYLOAD_OTPPARAMETERS, + "__module__": "google_auth_pb2" + # @@protoc_insertion_point(class_scope:MigrationPayload.OtpParameters) + }, + ), + "DESCRIPTOR": _MIGRATIONPAYLOAD, + "__module__": "google_auth_pb2" + # @@protoc_insertion_point(class_scope:MigrationPayload) + }, +) +_sym_db.RegisterMessage(MigrationPayload) +_sym_db.RegisterMessage(MigrationPayload.OtpParameters) + + +# @@protoc_insertion_point(module_scope) diff --git a/app/settings/index.html b/app/settings/index.html index e90dec15..b24211e6 100644 --- a/app/settings/index.html +++ b/app/settings/index.html @@ -18,13 +18,17 @@

Settings

You can configure the app setting here.

Launch on startup

-

Start the app after operating system loaded. App will start on the tray . Windows only.

+

Start the app after the operating system loaded. The app will start on the tray. Windows only.


+

Close app to tray

+

On closing the app will not quit. You can open the app from the tray menu. Windows only.

+ +

Clear data

Clear password, 2FA codes and other settings

-

Authme 1.2.2

+

Authme 1.3.0

diff --git a/app/settings/src/css/index.css b/app/settings/src/css/index.css index 70a521ab..3cfcf559 100644 --- a/app/settings/src/css/index.css +++ b/app/settings/src/css/index.css @@ -6,7 +6,7 @@ body { .center { top: -50px; width: 1000px; - height: 850px; + height: 1050px; } .button1 { diff --git a/app/settings/src/js/index.js b/app/settings/src/js/index.js index 7dde157a..97fa2606 100644 --- a/app/settings/src/js/index.js +++ b/app/settings/src/js/index.js @@ -4,14 +4,15 @@ const electron = require("electron") const ipc = electron.ipcRenderer const path = require("path") +const file_path = path.join(process.env.APPDATA, "/Levminer/Authme") + let but0 = document.querySelector("#but0") let but1 = document.querySelector("#but1") +let but2 = document.querySelector("#but2") //? startup let startup_state = true -const file_path = path.join(process.env.APPDATA, "/Levminer/Authme") - fs.readFile(path.join(file_path, "saos.md"), "utf-8", (err, data) => { if (err) { but0.textContent = "Off" @@ -50,7 +51,54 @@ let startup = () => { but0.textContent = "Off" startup_state = true - after_startup0() + after_tray0() + } + }) + } +} + +//? tray +let tray_state = true + +fs.readFile(path.join(file_path, "catt.md"), "utf-8", (err, data) => { + if (err) { + but2.textContent = "Off" + tray_state = true + + after_tray0() + } else { + but2.textContent = "On" + tray_state = false + + after_tray1() + } +}) + +let tray = () => { + if (tray_state == true) { + fs.writeFile(path.join(file_path, "catt.md"), "catt", (err) => { + if (err) { + console.log("Close app to tray don't created!") + } else { + console.log("Close app to tray file created!") + + but2.textContent = "On" + tray_state = false + + after_tray1() + } + }) + } else { + fs.unlink(path.join(file_path, "catt.md"), (err) => { + if (err && err.code === "ENOENT") { + return console.log("catt.md not deleted") + } else { + console.log("catt.md deleted") + + but2.textContent = "Off" + tray_state = true + + after_tray0() } }) } @@ -112,7 +160,7 @@ let data = () => { } let hide = () => { - after_hide() + ipc.send("hide0") } //? after_data @@ -129,7 +177,11 @@ let after_startup1 = () => { ipc.send("after_startup1") } -//? hide -let after_hide = () => { - ipc.send("hide") +//? after_tray +let after_tray0 = () => { + ipc.send("after_tray0") +} + +let after_tray1 = () => { + ipc.send("after_tray1") } diff --git a/main.js b/main.js index 46473591..fe226b41 100644 --- a/main.js +++ b/main.js @@ -9,6 +9,7 @@ let window0 let window1 let window2 let window3 +let window4 let c0 = false let c1 = false @@ -16,17 +17,23 @@ let c1 = false let c2 = false let c3 = false +let c4 = false +let c5 = false + let ipc0 = false let ipc1 = false let ipc2 = false let confirmed = false -let authme_version = "1.2.2" +let authme_version = "1.3.0" let node_version = process.versions.node let chrome_version = process.versions.chrome let electron_version = process.versions.electron +let to_tray = false +let show_tray = false + let createWindow = () => { window0 = new BrowserWindow({ webPreferences: { @@ -56,19 +63,37 @@ let createWindow = () => { }, }) + window4 = new BrowserWindow({ + webPreferences: { + preload: path.join(__dirname, "preload.js"), + nodeIntegration: true, + }, + }) + + window5 = new BrowserWindow({ + webPreferences: { + preload: path.join(__dirname, "preload.js"), + nodeIntegration: true, + }, + }) + // DEVTOOLS - /* window1.webContents.openDevTools() */ + /* window5.webContents.openDevTools() */ window0.maximize() window1.hide() window2.hide() window3.hide() + window4.hide() + window5.hide() window0.loadFile("./app/landing/index.html") window1.loadFile("./app/confirm/index.html") window2.loadFile("./app/application/index.html") window3.loadFile("./app/settings/index.html") + window4.loadFile("./app/import/index.html") + window5.loadFile("./app/export/index.html") window0.on("close", () => { app.quit() @@ -78,11 +103,37 @@ let createWindow = () => { app.quit() }) - window2.on("close", () => { + window2.on("close", async (e) => { + if (to_tray == false) { + app.exit() + } else { + e.preventDefault() + setTimeout(() => { + window2.hide() + }, 100) + c2 = false + show_tray = true + } + }) + + window3.on("close", async (e) => { + if (to_tray == false) { + app.exit() + } else { + e.preventDefault() + setTimeout(() => { + window3.hide() + }, 100) + c3 = false + show_tray = true + } + }) + + window4.on("close", () => { app.quit() }) - window3.on("close", () => { + window5.on("close", () => { app.quit() }) } @@ -114,7 +165,7 @@ ipc.on("to_application1", () => { } }) -ipc.on("hide", () => { +ipc.on("hide0", () => { if (c3 == false) { window3.maximize() window3.show() @@ -125,6 +176,28 @@ ipc.on("hide", () => { } }) +ipc.on("hide1", () => { + if (c4 == false) { + window4.maximize() + window4.show() + c4 = true + } else { + window4.hide() + c4 = false + } +}) + +ipc.on("hide2", () => { + if (c5 == false) { + window5.maximize() + window5.show() + c5 = true + } else { + window5.hide() + c5 = false + } +}) + ipc.on("after_data", () => { setTimeout(() => { app.quit() @@ -154,6 +227,14 @@ ipc.on("after_startup1", () => { }) }) +ipc.on("after_tray0", () => { + to_tray = false +}) + +ipc.on("after_tray1", () => { + to_tray = true +}) + ipc.on("startup", () => { window2.hide() }) @@ -169,7 +250,10 @@ app.whenReady().then(() => { click: () => { const file_path = path.join(process.env.APPDATA, "/Levminer/Authme") - if (c2 == false) { + if (show_tray == false) { + window2.hide() + show_tray = true + } else if (c2 == false) { fs.readFile(path.join(file_path, "pass.md"), "utf-8", (err, data) => { if (err) { return console.log("Not found pass.md") @@ -213,7 +297,8 @@ app.whenReady().then(() => { { label: "Exit app", click: () => { - app.quit() + to_tray = false + app.exit() }, }, ]) @@ -247,7 +332,8 @@ app.whenReady().then(() => { { label: "Exit", click: () => { - app.quit() + to_tray = false + app.exit() }, }, ], @@ -262,11 +348,13 @@ app.whenReady().then(() => { window0.setFullScreen(true) window1.setFullScreen(true) window2.setFullScreen(true) + window3.setFullScreen(true) c0 = true } else { window0.setFullScreen(false) window1.setFullScreen(false) window2.setFullScreen(false) + window3.setFullScreen(false) c0 = false } console.log(`FC ${c0}`) @@ -283,12 +371,16 @@ app.whenReady().then(() => { window1.webContents.openDevTools() window2.webContents.openDevTools() window3.webContents.openDevTools() + window4.webContents.openDevTools() + window5.webContents.openDevTools() c1 = true } else { window0.webContents.closeDevTools() window1.webContents.closeDevTools() window2.webContents.closeDevTools() window3.webContents.closeDevTools() + window4.webContents.closeDevTools() + window5.webContents.closeDevTools() c1 = false } console.log(`DT ${c1}`) @@ -296,6 +388,40 @@ app.whenReady().then(() => { }, ], }, + { + label: "Advanced", + submenu: [ + { + label: "Import", + click: () => { + if (c4 == false) { + window4.maximize() + window4.show() + c4 = true + } else { + window4.hide() + c4 = false + } + }, + }, + { + type: "separator", + }, + { + label: "Export", + click: () => { + if (c5 == false) { + window5.maximize() + window5.show() + c5 = true + } else { + window5.hide() + c5 = false + } + }, + }, + ], + }, { label: "Info", submenu: [ diff --git a/package-lock.json b/package-lock.json index 98ca61db..344dfd57 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,9 +1,17 @@ { - "name": "electron-quick-start", - "version": "1.0.0", + "name": "authme", + "version": "1.3.0", "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/runtime": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.1.tgz", + "integrity": "sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, "@electron/get": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.12.2.tgz", @@ -21,6 +29,327 @@ "sumchecker": "^3.0.1" } }, + "@jimp/bmp": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.16.1.tgz", + "integrity": "sha512-iwyNYQeBawrdg/f24x3pQ5rEx+/GwjZcCXd3Kgc+ZUd+Ivia7sIqBsOnDaMZdKCBPlfW364ekexnlOqyVa0NWg==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1", + "bmp-js": "^0.1.0" + } + }, + "@jimp/core": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.16.1.tgz", + "integrity": "sha512-la7kQia31V6kQ4q1kI/uLimu8FXx7imWVajDGtwUG8fzePLWDFJyZl0fdIXVCL1JW2nBcRHidUot6jvlRDi2+g==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1", + "any-base": "^1.1.0", + "buffer": "^5.2.0", + "exif-parser": "^0.1.12", + "file-type": "^9.0.0", + "load-bmfont": "^1.3.1", + "mkdirp": "^0.5.1", + "phin": "^2.9.1", + "pixelmatch": "^4.0.2", + "tinycolor2": "^1.4.1" + } + }, + "@jimp/custom": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.16.1.tgz", + "integrity": "sha512-DNUAHNSiUI/j9hmbatD6WN/EBIyeq4AO0frl5ETtt51VN1SvE4t4v83ZA/V6ikxEf3hxLju4tQ5Pc3zmZkN/3A==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/core": "^0.16.1" + } + }, + "@jimp/gif": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.16.1.tgz", + "integrity": "sha512-r/1+GzIW1D5zrP4tNrfW+3y4vqD935WBXSc8X/wm23QTY9aJO9Lw6PEdzpYCEY+SOklIFKaJYUAq/Nvgm/9ryw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1", + "gifwrap": "^0.9.2", + "omggif": "^1.0.9" + } + }, + "@jimp/jpeg": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.16.1.tgz", + "integrity": "sha512-8352zrdlCCLFdZ/J+JjBslDvml+fS3Z8gttdml0We759PnnZGqrnPRhkOEOJbNUlE+dD4ckLeIe6NPxlS/7U+w==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1", + "jpeg-js": "0.4.2" + } + }, + "@jimp/plugin-blit": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.16.1.tgz", + "integrity": "sha512-fKFNARm32RoLSokJ8WZXHHH2CGzz6ire2n1Jh6u+XQLhk9TweT1DcLHIXwQMh8oR12KgjbgsMGvrMVlVknmOAg==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-blur": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.16.1.tgz", + "integrity": "sha512-1WhuLGGj9MypFKRcPvmW45ht7nXkOKu+lg3n2VBzIB7r4kKNVchuI59bXaCYQumOLEqVK7JdB4glaDAbCQCLyw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-circle": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-circle/-/plugin-circle-0.16.1.tgz", + "integrity": "sha512-JK7yi1CIU7/XL8hdahjcbGA3V7c+F+Iw+mhMQhLEi7Q0tCnZ69YJBTamMiNg3fWPVfMuvWJJKOBRVpwNTuaZRg==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-color": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.16.1.tgz", + "integrity": "sha512-9yQttBAO5SEFj7S6nJK54f+1BnuBG4c28q+iyzm1JjtnehjqMg6Ljw4gCSDCvoCQ3jBSYHN66pmwTV74SU1B7A==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1", + "tinycolor2": "^1.4.1" + } + }, + "@jimp/plugin-contain": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.16.1.tgz", + "integrity": "sha512-44F3dUIjBDHN+Ym/vEfg+jtjMjAqd2uw9nssN67/n4FdpuZUVs7E7wadKY1RRNuJO+WgcD5aDQcsvurXMETQTg==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-cover": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.16.1.tgz", + "integrity": "sha512-YztWCIldBAVo0zxcQXR+a/uk3/TtYnpKU2CanOPJ7baIuDlWPsG+YE4xTsswZZc12H9Kl7CiziEbDtvF9kwA/Q==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-crop": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.16.1.tgz", + "integrity": "sha512-UQdva9oQzCVadkyo3T5Tv2CUZbf0klm2cD4cWMlASuTOYgaGaFHhT9st+kmfvXjKL8q3STkBu/zUPV6PbuV3ew==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-displace": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.16.1.tgz", + "integrity": "sha512-iVAWuz2+G6Heu8gVZksUz+4hQYpR4R0R/RtBzpWEl8ItBe7O6QjORAkhxzg+WdYLL2A/Yd4ekTpvK0/qW8hTVw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-dither": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.16.1.tgz", + "integrity": "sha512-tADKVd+HDC9EhJRUDwMvzBXPz4GLoU6s5P7xkVq46tskExYSptgj5713J5Thj3NMgH9Rsqu22jNg1H/7tr3V9Q==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-fisheye": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-fisheye/-/plugin-fisheye-0.16.1.tgz", + "integrity": "sha512-BWHnc5hVobviTyIRHhIy9VxI1ACf4CeSuCfURB6JZm87YuyvgQh5aX5UDKtOz/3haMHXBLP61ZBxlNpMD8CG4A==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-flip": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.16.1.tgz", + "integrity": "sha512-KdxTf0zErfZ8DyHkImDTnQBuHby+a5YFdoKI/G3GpBl3qxLBvC+PWkS2F/iN3H7wszP7/TKxTEvWL927pypT0w==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-gaussian": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.16.1.tgz", + "integrity": "sha512-u9n4wjskh3N1mSqketbL6tVcLU2S5TEaFPR40K6TDv4phPLZALi1Of7reUmYpVm8mBDHt1I6kGhuCJiWvzfGyg==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-invert": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.16.1.tgz", + "integrity": "sha512-2DKuyVXANH8WDpW9NG+PYFbehzJfweZszFYyxcaewaPLN0GxvxVLOGOPP1NuUTcHkOdMFbE0nHDuB7f+sYF/2w==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-mask": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.16.1.tgz", + "integrity": "sha512-snfiqHlVuj4bSFS0v96vo2PpqCDMe4JB+O++sMo5jF5mvGcGL6AIeLo8cYqPNpdO6BZpBJ8MY5El0Veckhr39Q==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-normalize": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.16.1.tgz", + "integrity": "sha512-dOQfIOvGLKDKXPU8xXWzaUeB0nvkosHw6Xg1WhS1Z5Q0PazByhaxOQkSKgUryNN/H+X7UdbDvlyh/yHf3ITRaw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-print": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.16.1.tgz", + "integrity": "sha512-ceWgYN40jbN4cWRxixym+csyVymvrryuKBQ+zoIvN5iE6OyS+2d7Mn4zlNgumSczb9GGyZZESIgVcBDA1ezq0Q==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1", + "load-bmfont": "^1.4.0" + } + }, + "@jimp/plugin-resize": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.16.1.tgz", + "integrity": "sha512-u4JBLdRI7dargC04p2Ha24kofQBk3vhaf0q8FwSYgnCRwxfvh2RxvhJZk9H7Q91JZp6wgjz/SjvEAYjGCEgAwQ==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-rotate": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.16.1.tgz", + "integrity": "sha512-ZUU415gDQ0VjYutmVgAYYxC9Og9ixu2jAGMCU54mSMfuIlmohYfwARQmI7h4QB84M76c9hVLdONWjuo+rip/zg==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-scale": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.16.1.tgz", + "integrity": "sha512-jM2QlgThIDIc4rcyughD5O7sOYezxdafg/2Xtd1csfK3z6fba3asxDwthqPZAgitrLgiKBDp6XfzC07Y/CefUw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-shadow": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-shadow/-/plugin-shadow-0.16.1.tgz", + "integrity": "sha512-MeD2Is17oKzXLnsphAa1sDstTu6nxscugxAEk3ji0GV1FohCvpHBcec0nAq6/czg4WzqfDts+fcPfC79qWmqrA==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-threshold": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-threshold/-/plugin-threshold-0.16.1.tgz", + "integrity": "sha512-iGW8U/wiCSR0+6syrPioVGoSzQFt4Z91SsCRbgNKTAk7D+XQv6OI78jvvYg4o0c2FOlwGhqz147HZV5utoSLxA==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugins": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.16.1.tgz", + "integrity": "sha512-c+lCqa25b+4q6mJZSetlxhMoYuiltyS+ValLzdwK/47+aYsq+kcJNl+TuxIEKf59yr9+5rkbpsPkZHLF/V7FFA==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/plugin-blit": "^0.16.1", + "@jimp/plugin-blur": "^0.16.1", + "@jimp/plugin-circle": "^0.16.1", + "@jimp/plugin-color": "^0.16.1", + "@jimp/plugin-contain": "^0.16.1", + "@jimp/plugin-cover": "^0.16.1", + "@jimp/plugin-crop": "^0.16.1", + "@jimp/plugin-displace": "^0.16.1", + "@jimp/plugin-dither": "^0.16.1", + "@jimp/plugin-fisheye": "^0.16.1", + "@jimp/plugin-flip": "^0.16.1", + "@jimp/plugin-gaussian": "^0.16.1", + "@jimp/plugin-invert": "^0.16.1", + "@jimp/plugin-mask": "^0.16.1", + "@jimp/plugin-normalize": "^0.16.1", + "@jimp/plugin-print": "^0.16.1", + "@jimp/plugin-resize": "^0.16.1", + "@jimp/plugin-rotate": "^0.16.1", + "@jimp/plugin-scale": "^0.16.1", + "@jimp/plugin-shadow": "^0.16.1", + "@jimp/plugin-threshold": "^0.16.1", + "timm": "^1.6.1" + } + }, + "@jimp/png": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.16.1.tgz", + "integrity": "sha512-iyWoCxEBTW0OUWWn6SveD4LePW89kO7ZOy5sCfYeDM/oTPLpR8iMIGvZpZUz1b8kvzFr27vPst4E5rJhGjwsdw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1", + "pngjs": "^3.3.3" + } + }, + "@jimp/tiff": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.16.1.tgz", + "integrity": "sha512-3K3+xpJS79RmSkAvFMgqY5dhSB+/sxhwTFA9f4AVHUK0oKW+u6r52Z1L0tMXHnpbAdR9EJ+xaAl2D4x19XShkQ==", + "requires": { + "@babel/runtime": "^7.7.2", + "utif": "^2.0.1" + } + }, + "@jimp/types": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.16.1.tgz", + "integrity": "sha512-g1w/+NfWqiVW4CaXSJyD28JQqZtm2eyKMWPhBBDCJN9nLCN12/Az0WFF3JUAktzdsEC2KRN2AqB1a2oMZBNgSQ==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/bmp": "^0.16.1", + "@jimp/gif": "^0.16.1", + "@jimp/jpeg": "^0.16.1", + "@jimp/png": "^0.16.1", + "@jimp/tiff": "^0.16.1", + "timm": "^1.6.1" + } + }, + "@jimp/utils": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.16.1.tgz", + "integrity": "sha512-8fULQjB0x4LzUSiSYG6ZtQl355sZjxbv8r9PPAuYHzS9sGiSHJQavNqK/nKnpDsVkU88/vRGcE7t3nMU0dEnVw==", + "requires": { + "@babel/runtime": "^7.7.2", + "regenerator-runtime": "^0.13.3" + } + }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -80,6 +409,19 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "any-base": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz", + "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==" + }, "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", @@ -132,8 +474,7 @@ "base64-js": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" }, "bcrypt": { "version": "5.0.0", @@ -150,6 +491,11 @@ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, + "bmp-js": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", + "integrity": "sha1-4Fpj95amwf8l9Hcex62twUjAcjM=" + }, "boolean": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.0.1.tgz", @@ -166,11 +512,19 @@ "concat-map": "0.0.1" } }, + "buffer": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", + "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, "buffer-alloc": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dev": true, "requires": { "buffer-alloc-unsafe": "^1.1.0", "buffer-fill": "^1.0.0" @@ -179,8 +533,7 @@ "buffer-alloc-unsafe": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" }, "buffer-crc32": { "version": "0.2.13", @@ -188,17 +541,20 @@ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", "dev": true }, + "buffer-equal": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", + "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=" + }, "buffer-fill": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", - "dev": true + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, "cacheable-request": { "version": "6.1.0", @@ -232,6 +588,11 @@ } } }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, "chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", @@ -243,6 +604,46 @@ "integrity": "sha1-BKEGZywYsIWrd02YPfo+oTjyIgU=", "dev": true }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, "clone-response": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", @@ -257,6 +658,19 @@ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, "commander": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", @@ -333,6 +747,11 @@ "ms": "^2.1.1" } }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, "decompress-response": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", @@ -380,6 +799,16 @@ "dev": true, "optional": true }, + "dijkstrajs": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz", + "integrity": "sha1-082BIh4+pAdCz83lVtTpnpjdxxs=" + }, + "dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" + }, "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -387,9 +816,9 @@ "dev": true }, "electron": { - "version": "10.1.3", - "resolved": "https://registry.npmjs.org/electron/-/electron-10.1.3.tgz", - "integrity": "sha512-CR8LrlG47MdAp317SQ3vGYa2o2cIMdMSMPYH46OVitFLk35dwE9fn3VqvhUIXhCHYcNWIAPzMhkVHpkoFdKWuw==", + "version": "10.1.4", + "resolved": "https://registry.npmjs.org/electron/-/electron-10.1.4.tgz", + "integrity": "sha512-5wiiGsif8jd1lS3Qhe9j8oQvUMnoWCvqBwYzzn+BGXGDq8aN8oTdM+j/2NY35Ktt3JrJdjKWcu9b7pDo8kNjbw==", "dev": true, "requires": { "@electron/get": "^1.0.1", @@ -544,6 +973,11 @@ } } }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -589,6 +1023,11 @@ "dev": true, "optional": true }, + "exif-parser": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", + "integrity": "sha1-WKnS1ywCwfbwKg70qRZicrd2CSI=" + }, "extract-zip": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", @@ -627,6 +1066,11 @@ "pend": "~1.2.0" } }, + "file-type": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz", + "integrity": "sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw==" + }, "filename-reserved-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", @@ -748,6 +1192,11 @@ "wide-align": "^1.1.0" } }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, "get-package-info": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-package-info/-/get-package-info-1.0.0.tgz", @@ -786,6 +1235,15 @@ "pump": "^3.0.0" } }, + "gifwrap": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.9.2.tgz", + "integrity": "sha512-fcIswrPaiCDAyO8xnWvHSZdWChjKXUanKKpAiWWJ/UTkEi/aYKn5+90e7DE820zbEaVR9CE2y4z9bzhQijZ0BA==", + "requires": { + "image-q": "^1.1.1", + "omggif": "^1.0.10" + } + }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -799,6 +1257,15 @@ "path-is-absolute": "^1.0.0" } }, + "global": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", + "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", + "requires": { + "min-document": "^2.19.0", + "process": "~0.5.1" + } + }, "global-agent": { "version": "2.1.12", "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.12.tgz", @@ -888,6 +1355,11 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + }, "ignore-walk": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", @@ -896,6 +1368,11 @@ "minimatch": "^3.0.4" } }, + "image-q": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/image-q/-/image-q-1.1.1.tgz", + "integrity": "sha1-/IQJlmRGC5DKhi2TALa/u7+/gFY=" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -929,6 +1406,11 @@ "number-is-nan": "^1.0.0" } }, + "is-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", + "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -943,6 +1425,23 @@ "buffer-alloc": "^1.2.0" } }, + "jimp": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.16.1.tgz", + "integrity": "sha512-+EKVxbR36Td7Hfd23wKGIeEyHbxShZDX6L8uJkgVW3ESA9GiTEPK08tG1XI2r/0w5Ch0HyJF5kPqF9K7EmGjaw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/custom": "^0.16.1", + "@jimp/plugins": "^0.16.1", + "@jimp/types": "^0.16.1", + "regenerator-runtime": "^0.13.3" + } + }, + "jpeg-js": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.2.tgz", + "integrity": "sha512-+az2gi/hvex7eLTMTlbRLOhH6P6WFdk2ITI8HJsaH2VqYO0I594zXSYEP+tf4FW+8Cy68ScDXoAsQdyQanv3sw==" + }, "json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", @@ -980,6 +1479,21 @@ "json-buffer": "3.0.0" } }, + "load-bmfont": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.1.tgz", + "integrity": "sha512-8UyQoYmdRDy81Brz6aLAUhfZLwr5zV0L3taTQ4hju7m6biuwiWiJXjPhBJxbUQJA8PrkvJ/7Enqmwk2sM14soA==", + "requires": { + "buffer-equal": "0.0.1", + "mime": "^1.3.4", + "parse-bmfont-ascii": "^1.0.3", + "parse-bmfont-binary": "^1.0.5", + "parse-bmfont-xml": "^1.1.4", + "phin": "^2.9.1", + "xhr": "^2.0.1", + "xtend": "^4.0.0" + } + }, "load-json-file": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", @@ -1039,12 +1553,25 @@ "escape-string-regexp": "^4.0.0" } }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, "mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "dev": true }, + "min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "requires": { + "dom-walk": "^0.1.0" + } + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -1234,6 +1761,11 @@ "dev": true, "optional": true }, + "omggif": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", + "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==" + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -1291,6 +1823,11 @@ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, "parse-author": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/parse-author/-/parse-author-2.0.0.tgz", @@ -1300,6 +1837,30 @@ "author-regex": "^1.0.0" } }, + "parse-bmfont-ascii": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz", + "integrity": "sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU=" + }, + "parse-bmfont-binary": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz", + "integrity": "sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY=" + }, + "parse-bmfont-xml": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz", + "integrity": "sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==", + "requires": { + "xml-parse-from-string": "^1.0.0", + "xml2js": "^0.4.5" + } + }, + "parse-headers": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.3.tgz", + "integrity": "sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA==" + }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -1312,8 +1873,7 @@ "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" }, "path-is-absolute": { "version": "1.0.1", @@ -1349,6 +1909,11 @@ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", "dev": true }, + "phin": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz", + "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==" + }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", @@ -1356,6 +1921,14 @@ "dev": true, "optional": true }, + "pixelmatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz", + "integrity": "sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=", + "requires": { + "pngjs": "^3.0.0" + } + }, "plist": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz", @@ -1367,12 +1940,22 @@ "xmldom": "0.1.x" } }, + "pngjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", + "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==" + }, "prepend-http": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", "dev": true }, + "process": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", + "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=" + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -1401,6 +1984,32 @@ "once": "^1.3.1" } }, + "qrcode": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.4.4.tgz", + "integrity": "sha512-oLzEC5+NKFou9P0bMj5+v6Z40evexeE29Z9cummZXZ9QXyMr3lphkURzxjXgPJC5azpxcshoDWV1xE46z+/c3Q==", + "requires": { + "buffer": "^5.4.3", + "buffer-alloc": "^1.2.0", + "buffer-from": "^1.1.1", + "dijkstrajs": "^1.0.1", + "isarray": "^2.0.1", + "pngjs": "^3.3.0", + "yargs": "^13.2.4" + }, + "dependencies": { + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + } + } + }, + "qrcode-reader": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/qrcode-reader/-/qrcode-reader-1.0.4.tgz", + "integrity": "sha512-rRjALGNh9zVqvweg1j5OKIQKNsw3bLC+7qwlnead5K/9cb1cEIAGkwikt/09U0K+2IDWGD9CC6SP7tHAjUeqvQ==" + }, "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -1453,6 +2062,21 @@ "util-deprecate": "~1.0.1" } }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, "resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", @@ -1675,6 +2299,16 @@ "yallist": "^3.0.3" } }, + "timm": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/timm/-/timm-1.7.1.tgz", + "integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==" + }, + "tinycolor2": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz", + "integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==" + }, "to-readable-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", @@ -1748,6 +2382,14 @@ "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=", "dev": true }, + "utif": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/utif/-/utif-2.0.1.tgz", + "integrity": "sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg==", + "requires": { + "pako": "^1.0.5" + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -1763,6 +2405,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, "wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", @@ -1771,11 +2418,83 @@ "string-width": "^1.0.2 || 2" } }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, + "xhr": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz", + "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==", + "requires": { + "global": "~4.3.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "xml-parse-from-string": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz", + "integrity": "sha1-qQKekp09vN7RafPG4oI42VpdWig=" + }, + "xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "dependencies": { + "xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" + } + } + }, "xmlbuilder": { "version": "9.0.7", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", @@ -1788,11 +2507,115 @@ "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==", "dev": true }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + }, "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, "yargs-parser": { "version": "19.0.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-19.0.1.tgz", diff --git a/package.json b/package.json index a3fec98a..8ba2a7c9 100644 --- a/package.json +++ b/package.json @@ -1,23 +1,31 @@ { - "name": "electron-quick-start", - "version": "1.0.0", - "description": "A minimal Electron application", + "name": "authme", + "version": "1.3.0", + "description": "A simple 2FA app for desktop built with Electron and Node.js.", "main": "main.js", "scripts": { - "start": "electron ." + "start": "electron .", + "build": "electron-packager . Authme --overwrite --platform=all --arch=x64 --icon=img/icon.icns --out=build" }, - "repository": "https://github.com/electron/electron-quick-start", - "keywords": [], - "author": "GitHub", - "license": "CC0-1.0", + "repository": "https://github.com/Levminer/authme", + "keywords": [ + "authme", + "2fa-security", + "2fa-client" + ], + "author": "Levminer", + "license": "MIT", "devDependencies": { - "electron": "^10.1.3", + "electron": "^10.1.4", "electron-packager": "^15.0.0" }, "dependencies": { "bcrypt": "^5.0.0", "create-desktop-shortcuts": "^1.1.0", "cryptr": "^6.0.2", + "jimp": "^0.16.1", + "qrcode": "^1.4.4", + "qrcode-reader": "^1.0.4", "speakeasy": "^2.0.0" } }