feat!: add totp by link "otpauth" function implemented

This commit is contained in:
Pavel-Savely Savianok 2024-12-30 01:05:30 +03:00
parent 4dbc3828fd
commit 14cc456d0e
3 changed files with 69 additions and 7 deletions

View File

@ -15,8 +15,8 @@ Page(
app._options.globalData.TOTPS = x app._options.globalData.TOTPS = x
this.initPage(); this.initPage();
}) })
.catch((x) => { .catch(() => {
app._options.globalData.TOTPS = localStorage.getItem('TOTPs') app._options.globalData.TOTPS = localStorage.getItem('TOTPs') ?? []
this.initPage() this.initPage()
}) })
}, },

View File

@ -1,10 +1,31 @@
import { getTOTPByLink } from './utils/queryParser.js'
let _props = null; let _props = null;
AppSettingsPage({ AppSettingsPage({
build(props) { build(props) {
_props = props; _props = props;
const storage = props.settingsStorage.getItem("TOTPs"); const storage = props.settingsStorage.getItem("TOTPs")
const totpEntrys = GetTOTPList(storage); const totpEntrys = GetTOTPList(storage)
const createButton = TextInput({
placeholder: "otpauth://",
label: "Add new OTP Link",
onChange: (changes) => {
storage.push(getTOTPByLink(changes))
updateStorage(storage)
},
labelStyle: {
backgroundColor: "#14213D",
display: "flex",
alignItems: "center",
justifyContent: "center",
margin: "10px",
flexGrow: 1,
fontSize: "20px",
color: "#FFFFFF",
borderRadius: "5px"
}
});
var body = Section( var body = Section(
{ {
@ -34,7 +55,8 @@ AppSettingsPage({
"TOTPS:" "TOTPS:"
) )
), ),
...totpEntrys ...totpEntrys,
createButton
] ]
); );
return body; return body;
@ -47,8 +69,12 @@ function GetTOTPList(storage){
storage.forEach((element) => { storage.forEach((element) => {
const elementId = counter; const elementId = counter;
const textInput = TextInput({ const textInput = TextInput({
placeholder: "otplink", placeholder: "otpauth://",
label: "Change OTP link", label: "Change OTP link",
onChange: (changes) => {
storage[elementId] = getTOTPByLink(changes)
updateStorage(storage)
},
labelStyle: { labelStyle: {
backgroundColor: "#14213D", backgroundColor: "#14213D",
textAlign: "center", textAlign: "center",
@ -75,7 +101,7 @@ function GetTOTPList(storage){
); );
const delButton = Button( const delButton = Button(
{ {
onClick: (el) => { onClick: () => {
storage = storage.filter(x => storage.indexOf(x) != elementId) storage = storage.filter(x => storage.indexOf(x) != elementId)
updateStorage(storage) updateStorage(storage)
}, },

View File

@ -0,0 +1,36 @@
import { TOTP } from "../../lib/totp-quickjs";
const otpScheme = "otpauth:/";
export function getTOTPByLink(link){
let args = link.split("/", otpScheme.length)
let type = args[2] //Returns 'hotp' or 'totp'
let issuer = args[3].split(':')[0]?.split('?')[0] //Returns issuer
let client = args[3].split(':')[1]?.split('?')[0] ?? args[3].split(':')[0]?.split('?')[0] //Returns client
let secret = args[3].split('secret=')[1]?.split('&')[0] //Returns secret
let period = args[3].split('period=')[1]?.split('&')[0] //Returns period
let digits = args[3].split('digits=')[1]?.split('&')[0] //Returns digits
let algorithm = args[3].split('algorithm=')[1]?.split('&')[0] //Returns algorithm
if(type.toLowerCase() != 'totp')
return Error("Type is not valid, requires 'TOTP'")
if(secret === undefined)
return Error("Secret not defined")
issuer = issuer.replace("%20", " ")
client = client.replace("%20", " ")
return new TOTP(secret, issuer, client, digits, period, 0, getHashType(algorithm))
}
function getHashType(algorithm){
if(algorithm == "SHA1")
return "SHA-1"
if(algorithm == "SHA256")
return "SHA-256"
if(algorithm == "SHA512")
return "SHA-512"
else
return null
}