mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-15 23:47:33 +08:00
code refactor
This commit is contained in:
+9
-9
@@ -2,7 +2,7 @@ import { defaultLanguage, allLanguages } from '../locales/index.js';
|
||||
import timezone from "../consts/timezone.js";
|
||||
import currency from "../consts/currency.js";
|
||||
import settings from "./settings.js";
|
||||
import utils from './utils.js';
|
||||
import utilities from './utilities/index.js';
|
||||
|
||||
const apiNotFoundErrorCode = 100001;
|
||||
const specifiedApiNotFoundErrors = {
|
||||
@@ -251,16 +251,16 @@ export function getAllMinWeekdayNames(translateFn) {
|
||||
}
|
||||
|
||||
export function getAllTimezones(includeSystemDefault, translateFn) {
|
||||
const defaultTimezoneOffset = utils.getTimezoneOffset();
|
||||
const defaultTimezoneOffsetMinutes = utils.getTimezoneOffsetMinutes();
|
||||
const defaultTimezoneOffset = utilities.getTimezoneOffset();
|
||||
const defaultTimezoneOffsetMinutes = utilities.getTimezoneOffsetMinutes();
|
||||
const allTimezones = timezone.all;
|
||||
const allTimezoneInfos = [];
|
||||
|
||||
for (let i = 0; i < allTimezones.length; i++) {
|
||||
allTimezoneInfos.push({
|
||||
name: allTimezones[i].timezoneName,
|
||||
utcOffset: (allTimezones[i].timezoneName !== timezone.utcTimezoneName ? utils.getTimezoneOffset(allTimezones[i].timezoneName) : ''),
|
||||
utcOffsetMinutes: utils.getTimezoneOffsetMinutes(allTimezones[i].timezoneName),
|
||||
utcOffset: (allTimezones[i].timezoneName !== timezone.utcTimezoneName ? utilities.getTimezoneOffset(allTimezones[i].timezoneName) : ''),
|
||||
utcOffsetMinutes: utilities.getTimezoneOffsetMinutes(allTimezones[i].timezoneName),
|
||||
displayName: translateFn(`timezone.${allTimezones[i].displayName}`)
|
||||
});
|
||||
}
|
||||
@@ -311,22 +311,22 @@ export function getAllCurrencies(translateFn) {
|
||||
}
|
||||
|
||||
export function getDisplayCurrency(value, currencyCode, notConvertValue, translateFn) {
|
||||
if (!utils.isNumber(value) && !utils.isString(value)) {
|
||||
if (!utilities.isNumber(value) && !utilities.isString(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (utils.isNumber(value)) {
|
||||
if (utilities.isNumber(value)) {
|
||||
value = value.toString();
|
||||
}
|
||||
|
||||
if (!notConvertValue) {
|
||||
const hasIncompleteFlag = utils.isString(value) && value.charAt(value.length - 1) === '+';
|
||||
const hasIncompleteFlag = utilities.isString(value) && value.charAt(value.length - 1) === '+';
|
||||
|
||||
if (hasIncompleteFlag) {
|
||||
value = value.substring(0, value.length - 1);
|
||||
}
|
||||
|
||||
value = utils.numericCurrencyToString(value);
|
||||
value = utilities.numericCurrencyToString(value);
|
||||
|
||||
if (hasIncompleteFlag) {
|
||||
value = value + '+';
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@ import axios from 'axios';
|
||||
|
||||
import api from '../consts/api.js';
|
||||
import userState from './userstate.js';
|
||||
import utils from './utils.js';
|
||||
import utilities from './utilities/index.js';
|
||||
|
||||
let needBlockRequest = false;
|
||||
let blockedRequests = [];
|
||||
@@ -16,7 +16,7 @@ axios.interceptors.request.use(config => {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
|
||||
config.headers['X-Timezone-Offset'] = utils.getTimezoneOffsetMinutes();
|
||||
config.headers['X-Timezone-Offset'] = utilities.getTimezoneOffsetMinutes();
|
||||
|
||||
if (needBlockRequest && !config.ignoreBlocked) {
|
||||
return new Promise(resolve => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import CryptoJS from 'crypto-js';
|
||||
|
||||
import settings from './settings.js';
|
||||
import utils from './utils.js';
|
||||
import utilities from './utilities/index.js';
|
||||
|
||||
const appLockSecretBaseStringPrefix = 'EBK_LOCK_SECRET_';
|
||||
|
||||
@@ -141,7 +141,7 @@ function isCorrectPinCode(pinCode) {
|
||||
}
|
||||
|
||||
function updateToken(token) {
|
||||
if (utils.isString(token)) {
|
||||
if (utilities.isString(token)) {
|
||||
if (settings.isEnableApplicationLock()) {
|
||||
sessionStorage.setItem(tokenSessionStorageKey, token);
|
||||
|
||||
@@ -155,7 +155,7 @@ function updateToken(token) {
|
||||
}
|
||||
|
||||
function updateUserInfo(user) {
|
||||
if (utils.isObject(user)) {
|
||||
if (utilities.isObject(user)) {
|
||||
localStorage.setItem(userInfoLocalStorageKey, JSON.stringify(user));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
import accountConstants from '../../consts/account.js';
|
||||
|
||||
export function getAccountCategoryInfo(categoryId) {
|
||||
for (let i = 0; i < accountConstants.allCategories.length; i++) {
|
||||
if (accountConstants.allCategories[i].id === categoryId) {
|
||||
return accountConstants.allCategories[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getCategorizedAccounts(allAccounts) {
|
||||
const ret = {};
|
||||
|
||||
for (let i = 0; i < allAccounts.length; i++) {
|
||||
const account = allAccounts[i];
|
||||
|
||||
if (!ret[account.category]) {
|
||||
const categoryInfo = getAccountCategoryInfo(account.category);
|
||||
|
||||
if (categoryInfo) {
|
||||
ret[account.category] = {
|
||||
category: account.category,
|
||||
name: categoryInfo.name,
|
||||
icon: categoryInfo.defaultAccountIconId,
|
||||
accounts: []
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (ret[account.category]) {
|
||||
const accountList = ret[account.category].accounts;
|
||||
accountList.push(account);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
export function getVisibleCategorizedAccounts(categorizedAccounts) {
|
||||
const ret = {};
|
||||
|
||||
for (let i = 0; i < accountConstants.allCategories.length; i++) {
|
||||
const accountCategory = accountConstants.allCategories[i];
|
||||
|
||||
if (!categorizedAccounts[accountCategory.id] || !categorizedAccounts[accountCategory.id].accounts) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const allAccounts = categorizedAccounts[accountCategory.id].accounts;
|
||||
const visibleAccounts = [];
|
||||
const allVisibleSubAccounts = {};
|
||||
|
||||
for (let j = 0; j < allAccounts.length; j++) {
|
||||
const account = allAccounts[j];
|
||||
|
||||
if (account.hidden) {
|
||||
continue;
|
||||
}
|
||||
|
||||
visibleAccounts.push(account);
|
||||
|
||||
if (account.type === accountConstants.allAccountTypes.MultiSubAccounts && account.subAccounts) {
|
||||
const visibleSubAccounts = [];
|
||||
|
||||
for (let k = 0; k < account.subAccounts.length; k++) {
|
||||
const subAccount = account.subAccounts[k];
|
||||
|
||||
if (!subAccount.hidden) {
|
||||
visibleSubAccounts.push(subAccount);
|
||||
}
|
||||
}
|
||||
|
||||
if (visibleSubAccounts.length > 0) {
|
||||
allVisibleSubAccounts[account.id] = visibleSubAccounts;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (visibleAccounts.length > 0) {
|
||||
ret[accountCategory.id] = {
|
||||
category: accountCategory.id,
|
||||
name: accountCategory.name,
|
||||
icon: accountCategory.defaultAccountIconId,
|
||||
visibleAccounts: visibleAccounts,
|
||||
visibleSubAccounts: allVisibleSubAccounts
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
export function getAllFilteredAccountsBalance(categorizedAccounts, accountFilter) {
|
||||
const allAccountCategories = accountConstants.allCategories;
|
||||
const ret = [];
|
||||
|
||||
for (let categoryIdx = 0; categoryIdx < allAccountCategories.length; categoryIdx++) {
|
||||
const accountCategory = allAccountCategories[categoryIdx];
|
||||
|
||||
if (!categorizedAccounts[accountCategory.id] || !categorizedAccounts[accountCategory.id].accounts) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (let accountIdx = 0; accountIdx < categorizedAccounts[accountCategory.id].accounts.length; accountIdx++) {
|
||||
const account = categorizedAccounts[accountCategory.id].accounts[accountIdx];
|
||||
|
||||
if (account.hidden || !accountFilter(account)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (account.type === accountConstants.allAccountTypes.SingleAccount) {
|
||||
ret.push({
|
||||
balance: account.balance,
|
||||
isAsset: account.isAsset,
|
||||
isLiability: account.isLiability,
|
||||
currency: account.currency
|
||||
});
|
||||
} else if (account.type === accountConstants.allAccountTypes.MultiSubAccounts) {
|
||||
for (let subAccountIdx = 0; subAccountIdx < account.subAccounts.length; subAccountIdx++) {
|
||||
const subAccount = account.subAccounts[subAccountIdx];
|
||||
|
||||
if (subAccount.hidden || !accountFilter(subAccount)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ret.push({
|
||||
balance: subAccount.balance,
|
||||
isAsset: subAccount.isAsset,
|
||||
isLiability: subAccount.isLiability,
|
||||
currency: subAccount.currency
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import categoryConstants from '../../consts/category.js';
|
||||
import transactionConstants from '../../consts/transaction.js';
|
||||
|
||||
export function transactionTypeToCategoryType(transactionType) {
|
||||
if (transactionType === transactionConstants.allTransactionTypes.Income) {
|
||||
return categoryConstants.allCategoryTypes.Income;
|
||||
} else if (transactionType === transactionConstants.allTransactionTypes.Expense) {
|
||||
return categoryConstants.allCategoryTypes.Expense;
|
||||
} else if (transactionType === transactionConstants.allTransactionTypes.Transfer) {
|
||||
return categoryConstants.allCategoryTypes.Transfer;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function categoryTypeToTransactionType(categoryType) {
|
||||
if (categoryType === categoryConstants.allCategoryTypes.Income) {
|
||||
return transactionConstants.allTransactionTypes.Income;
|
||||
} else if (categoryType === categoryConstants.allCategoryTypes.Expense) {
|
||||
return transactionConstants.allTransactionTypes.Expense;
|
||||
} else if (categoryType === categoryConstants.allCategoryTypes.Transfer) {
|
||||
return transactionConstants.allTransactionTypes.Transfer;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function allVisibleTransactionCategories(allTransactionCategories) {
|
||||
const ret = {};
|
||||
|
||||
for (let key in transactionConstants.allTransactionTypes) {
|
||||
if (!Object.prototype.hasOwnProperty.call(transactionConstants.allTransactionTypes, key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const transactionType = transactionConstants.allTransactionTypes[key];
|
||||
|
||||
if (!allTransactionCategories[transactionType]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const allCategories = allTransactionCategories[transactionType];
|
||||
const visibleCategories = [];
|
||||
const allVisibleSubCategories = {};
|
||||
|
||||
for (let j = 0; j < allCategories.length; j++) {
|
||||
const category = allCategories[j];
|
||||
|
||||
if (category.hidden) {
|
||||
continue;
|
||||
}
|
||||
|
||||
visibleCategories.push(category);
|
||||
|
||||
if (category.subCategories) {
|
||||
const visibleSubCategories = [];
|
||||
|
||||
for (let k = 0; k < category.subCategories.length; k++) {
|
||||
const subCategory = category.subCategories[k];
|
||||
|
||||
if (!subCategory.hidden) {
|
||||
visibleSubCategories.push(subCategory);
|
||||
}
|
||||
}
|
||||
|
||||
if (visibleSubCategories.length > 0) {
|
||||
allVisibleSubCategories[category.id] = visibleSubCategories;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret[transactionType.toString()] = {
|
||||
type: transactionType.toString(),
|
||||
visibleCategories: visibleCategories,
|
||||
visibleSubCategories: allVisibleSubCategories
|
||||
};
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
import settings from "../../lib/settings";
|
||||
|
||||
export function isFunction(val) {
|
||||
return typeof(val) === 'function';
|
||||
}
|
||||
|
||||
export function isObject(val) {
|
||||
return val != null && typeof(val) === 'object' && !isArray(val);
|
||||
}
|
||||
|
||||
export function isArray(val) {
|
||||
if (isFunction(Array.isArray)) {
|
||||
return Array.isArray(val);
|
||||
}
|
||||
|
||||
return Object.prototype.toString.call(val) === '[object Array]';
|
||||
}
|
||||
|
||||
export function isString(val) {
|
||||
return typeof(val) === 'string';
|
||||
}
|
||||
|
||||
export function isNumber(val) {
|
||||
return typeof(val) === 'number';
|
||||
}
|
||||
|
||||
export function isBoolean(val) {
|
||||
return typeof(val) === 'boolean';
|
||||
}
|
||||
|
||||
export function isEquals(obj1, obj2) {
|
||||
if (obj1 === obj2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isArray(obj1) && isArray(obj2)) {
|
||||
if (obj1.length !== obj2.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < obj1.length; i++) {
|
||||
if (!isEquals(obj1[i], obj2[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (isObject(obj1) && isObject(obj2)) {
|
||||
const keys1 = Object.keys(obj1);
|
||||
const keys2 = Object.keys(obj2);
|
||||
|
||||
if (keys1.length !== keys2.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const keyExistsMap2 = {};
|
||||
|
||||
for (let i = 0; i < keys2.length; i++) {
|
||||
const key = keys2[i];
|
||||
|
||||
keyExistsMap2[key] = true;
|
||||
}
|
||||
|
||||
for (let i = 0; i < keys1.length; i++) {
|
||||
const key = keys1[i];
|
||||
|
||||
if (!keyExistsMap2[key]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isEquals(obj1[key], obj2[key])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return obj1 === obj2;
|
||||
}
|
||||
}
|
||||
|
||||
export function appendThousandsSeparator(value) {
|
||||
if (!settings.isEnableThousandsSeparator() || value.length <= 3) {
|
||||
return value;
|
||||
}
|
||||
|
||||
const negative = value.charAt(0) === '-';
|
||||
|
||||
if (negative) {
|
||||
value = value.substring(1);
|
||||
}
|
||||
|
||||
const dotPos = value.indexOf('.');
|
||||
const integer = dotPos < 0 ? value : value.substring(0, dotPos);
|
||||
const decimals = dotPos < 0 ? '' : value.substring(dotPos + 1, value.length);
|
||||
|
||||
const finalChars = [];
|
||||
|
||||
for (let i = 0; i < integer.length; i++) {
|
||||
if (i % 3 === 0 && i > 0) {
|
||||
finalChars.push(',');
|
||||
}
|
||||
|
||||
finalChars.push(integer.charAt(integer.length - 1 - i));
|
||||
}
|
||||
|
||||
finalChars.reverse();
|
||||
|
||||
let newInteger = finalChars.join('');
|
||||
|
||||
if (negative) {
|
||||
newInteger = `-${newInteger}`;
|
||||
}
|
||||
|
||||
if (dotPos < 0) {
|
||||
return newInteger;
|
||||
} else {
|
||||
return `${newInteger}.${decimals}`;
|
||||
}
|
||||
}
|
||||
|
||||
export function formatPercent(value, precision, lowPrecisionValue) {
|
||||
const ratio = Math.pow(10, precision);
|
||||
const normalizedValue = Math.floor(value * ratio);
|
||||
|
||||
if (value > 0 && normalizedValue < 1 && lowPrecisionValue) {
|
||||
return lowPrecisionValue + '%';
|
||||
}
|
||||
|
||||
const result = normalizedValue / ratio;
|
||||
return result + '%';
|
||||
}
|
||||
|
||||
export function limitText(value, maxLength) {
|
||||
let length = 0;
|
||||
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
const c = value.charCodeAt(i);
|
||||
|
||||
if ((c >= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f)) {
|
||||
length++;
|
||||
} else {
|
||||
length += 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (length <= maxLength || maxLength <= 3) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return value.substring(0, maxLength - 3) + '...';
|
||||
}
|
||||
|
||||
export function base64encode(arrayBuffer) {
|
||||
if (!arrayBuffer || arrayBuffer.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
|
||||
}
|
||||
|
||||
export function arrayBufferToString(arrayBuffer) {
|
||||
return String.fromCharCode.apply(null, new Uint8Array(arrayBuffer));
|
||||
}
|
||||
|
||||
export function stringToArrayBuffer(str){
|
||||
return Uint8Array.from(str, c => c.charCodeAt(0)).buffer;
|
||||
}
|
||||
|
||||
export function getNameByKeyValue(src, value, keyField, nameField, defaultName) {
|
||||
if (isArray(src)) {
|
||||
if (keyField) {
|
||||
for (let i = 0; i < src.length; i++) {
|
||||
const option = src[i];
|
||||
|
||||
if (option[keyField] === value) {
|
||||
return option[nameField];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (src[value]) {
|
||||
const option = src[value];
|
||||
|
||||
return option[nameField];
|
||||
}
|
||||
}
|
||||
} else if (isObject(src)) {
|
||||
if (keyField) {
|
||||
for (let key in src) {
|
||||
if (!Object.prototype.hasOwnProperty.call(src, key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const option = src[key];
|
||||
|
||||
if (option[keyField] === value) {
|
||||
return option[nameField];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (src[value]) {
|
||||
const option = src[value];
|
||||
|
||||
return option[nameField];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return defaultName;
|
||||
}
|
||||
|
||||
export function copyObjectTo(fromObject, toObject) {
|
||||
if (!isObject(fromObject)) {
|
||||
return toObject;
|
||||
}
|
||||
|
||||
if (!isObject(toObject)) {
|
||||
toObject = {};
|
||||
}
|
||||
|
||||
for (let key in fromObject) {
|
||||
if (!Object.prototype.hasOwnProperty.call(fromObject, key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const fromValue = fromObject[key];
|
||||
const toValue = toObject[key];
|
||||
|
||||
if (isArray(fromValue)) {
|
||||
toObject[key] = this.copyArrayTo(fromValue, toValue);
|
||||
} else if (isObject(fromValue)) {
|
||||
toObject[key] = this.copyObjectTo(fromValue, toValue);
|
||||
} else {
|
||||
if (fromValue !== toValue) {
|
||||
toObject[key] = fromValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return toObject;
|
||||
}
|
||||
|
||||
export function copyArrayTo(fromArray, toArray) {
|
||||
if (!isArray(fromArray)) {
|
||||
return toArray;
|
||||
}
|
||||
|
||||
if (!isArray(toArray)) {
|
||||
toArray = [];
|
||||
}
|
||||
|
||||
for (let i = 0; i < fromArray.length; i++) {
|
||||
const fromValue = fromArray[i];
|
||||
|
||||
if (toArray.length > i) {
|
||||
const toValue = toArray[i];
|
||||
|
||||
if (isArray(fromValue)) {
|
||||
toArray[i] = this.copyArrayTo(fromValue, toValue);
|
||||
} else if (isObject(fromValue)) {
|
||||
toArray[i] = this.copyObjectTo(fromValue, toValue);
|
||||
} else {
|
||||
if (fromValue !== toValue) {
|
||||
toArray[i] = fromValue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isArray(fromValue)) {
|
||||
toArray.push(this.copyArrayTo(fromValue, []));
|
||||
} else if (isObject(fromValue)) {
|
||||
toArray.push(this.copyObjectTo(fromValue, {}));
|
||||
} else {
|
||||
toArray.push(fromValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return toArray;
|
||||
}
|
||||
|
||||
export function arrangeArrayWithNewStartIndex(array, startIndex) {
|
||||
if (startIndex <= 0 || startIndex >= array.length) {
|
||||
return array;
|
||||
}
|
||||
|
||||
const newArray = [];
|
||||
|
||||
for (let i = startIndex; i < array.length; i++) {
|
||||
newArray.push(array[i]);
|
||||
}
|
||||
|
||||
for (let i = 0; i < startIndex; i++) {
|
||||
newArray.push(array[i]);
|
||||
}
|
||||
|
||||
return newArray;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
import { isNumber, appendThousandsSeparator } from "./common.js";
|
||||
|
||||
export function numericCurrencyToString(num) {
|
||||
let str = num.toString();
|
||||
const negative = str.charAt(0) === '-';
|
||||
|
||||
if (negative) {
|
||||
str = str.substring(1);
|
||||
}
|
||||
|
||||
if (str.length === 0) {
|
||||
str = '0.00';
|
||||
} else if (str.length === 1) {
|
||||
str = '0.0' + str;
|
||||
} else if (str.length === 2) {
|
||||
str = '0.' + str;
|
||||
} else {
|
||||
let integer = str.substring(0, str.length - 2);
|
||||
let decimals = str.substring(str.length - 2);
|
||||
|
||||
integer = appendThousandsSeparator(integer);
|
||||
|
||||
str = `${integer}.${decimals}`;
|
||||
}
|
||||
|
||||
if (negative) {
|
||||
str = `-${str}`;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
export function stringCurrencyToNumeric(str) {
|
||||
if (!str || str.length < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const negative = str.charAt(0) === '-';
|
||||
|
||||
if (negative) {
|
||||
str = str.substring(1);
|
||||
}
|
||||
|
||||
if (!str || str.length < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const sign = negative ? -1 : 1;
|
||||
|
||||
if (str.indexOf(',')) {
|
||||
str = str.replaceAll(/,/g, '');
|
||||
}
|
||||
|
||||
let dotPos = str.indexOf('.');
|
||||
|
||||
if (dotPos < 0) {
|
||||
return sign * parseInt(str) * 100;
|
||||
} else if (dotPos === 0) {
|
||||
str = '0' + str;
|
||||
dotPos++;
|
||||
}
|
||||
|
||||
const integer = str.substring(0, dotPos);
|
||||
const decimals = str.substring(dotPos + 1, str.length);
|
||||
|
||||
if (decimals.length < 1) {
|
||||
return sign * parseInt(integer) * 100;
|
||||
} else if (decimals.length === 1) {
|
||||
return sign * parseInt(integer) * 100 + sign * parseInt(decimals) * 10;
|
||||
} else if (decimals.length === 2) {
|
||||
return sign * parseInt(integer) * 100 + sign * parseInt(decimals);
|
||||
} else {
|
||||
return sign * parseInt(integer) * 100 + sign * parseInt(decimals.substring(0, 2));
|
||||
}
|
||||
}
|
||||
|
||||
export function getExchangedAmount(amount, fromRate, toRate) {
|
||||
const exchangeRate = parseFloat(toRate) / parseFloat(fromRate);
|
||||
|
||||
if (!isNumber(exchangeRate)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return amount * exchangeRate;
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
import moment from 'moment';
|
||||
|
||||
import dateTimeConstants from '../../consts/datetime.js';
|
||||
import { isNumber } from "./common.js";
|
||||
|
||||
export function getUtcOffsetMinutesByUtcOffset(utcOffset) {
|
||||
if (!utcOffset) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const parts = utcOffset.split(':');
|
||||
|
||||
if (parts.length !== 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return parseInt(parts[0]) * 60 + parseInt(parts[1]);
|
||||
}
|
||||
|
||||
export function getUtcOffsetByUtcOffsetMinutes(utcOffsetMinutes) {
|
||||
let offsetHours = parseInt(Math.abs(utcOffsetMinutes) / 60);
|
||||
let offsetMinutes = Math.abs(utcOffsetMinutes) - offsetHours * 60;
|
||||
|
||||
if (offsetHours < 10) {
|
||||
offsetHours = '0' + offsetHours;
|
||||
}
|
||||
|
||||
if (offsetMinutes < 10) {
|
||||
offsetMinutes = '0' + offsetMinutes;
|
||||
}
|
||||
|
||||
if (utcOffsetMinutes >= 0) {
|
||||
return `+${offsetHours}:${offsetMinutes}`;
|
||||
} else if (utcOffsetMinutes < 0) {
|
||||
return `-${offsetHours}:${offsetMinutes}`;
|
||||
}
|
||||
}
|
||||
|
||||
export function getTimezoneOffset(timezone) {
|
||||
if (timezone) {
|
||||
return moment().tz(timezone).format('Z');
|
||||
} else {
|
||||
return moment().format('Z');
|
||||
}
|
||||
}
|
||||
|
||||
export function getTimezoneOffsetMinutes(timezone) {
|
||||
const utcOffset = getTimezoneOffset(timezone);
|
||||
return getUtcOffsetMinutesByUtcOffset(utcOffset);
|
||||
}
|
||||
|
||||
export function getBrowserTimezoneOffsetMinutes() {
|
||||
return -new Date().getTimezoneOffset();
|
||||
}
|
||||
|
||||
export function getLocalDatetimeFromUnixTime(unixTime) {
|
||||
return new Date(unixTime * 1000);
|
||||
}
|
||||
|
||||
export function getUnixTimeFromLocalDatetime(datetime) {
|
||||
return datetime.getTime() / 1000;
|
||||
}
|
||||
|
||||
export function getActualUnixTimeForStore(unixTime, utcOffset, currentUtcOffset) {
|
||||
return unixTime - (utcOffset - currentUtcOffset) * 60;
|
||||
}
|
||||
|
||||
export function getDummyUnixTimeForLocalUsage(unixTime, utcOffset, currentUtcOffset) {
|
||||
return unixTime + (utcOffset - currentUtcOffset) * 60;
|
||||
}
|
||||
|
||||
export function getCurrentUnixTime() {
|
||||
return moment().unix();
|
||||
}
|
||||
|
||||
export function getCurrentDateTime() {
|
||||
return moment();
|
||||
}
|
||||
|
||||
export function parseDateFromUnixTime(unixTime, utcOffset, currentUtcOffset) {
|
||||
if (isNumber(utcOffset)) {
|
||||
if (!isNumber(currentUtcOffset)) {
|
||||
currentUtcOffset = getTimezoneOffsetMinutes();
|
||||
}
|
||||
|
||||
unixTime = getDummyUnixTimeForLocalUsage(unixTime, utcOffset, currentUtcOffset);
|
||||
}
|
||||
|
||||
return moment.unix(unixTime);
|
||||
}
|
||||
|
||||
export function is24HourFormat(format) {
|
||||
if (format.indexOf('HH') >= 0 && format.indexOf('hh') < 0) {
|
||||
return true;
|
||||
} else if (format.indexOf('HH') < 0 && format.indexOf('hh') >= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function formatUnixTime(unixTime, format, utcOffset, currentUtcOffset) {
|
||||
return parseDateFromUnixTime(unixTime, utcOffset, currentUtcOffset).format(format);
|
||||
}
|
||||
|
||||
export function formatTime(dateTime, format) {
|
||||
return moment(dateTime).format(format);
|
||||
}
|
||||
|
||||
export function getUnixTime(date) {
|
||||
return moment(date).unix();
|
||||
}
|
||||
|
||||
export function getYear(date) {
|
||||
return moment(date).year();
|
||||
}
|
||||
|
||||
export function getMonth(date) {
|
||||
return moment(date).month() + 1;
|
||||
}
|
||||
|
||||
export function getYearAndMonth(date) {
|
||||
const year = getYear(date);
|
||||
let month = getMonth(date);
|
||||
|
||||
if (month < 10) {
|
||||
month = '0' + month;
|
||||
}
|
||||
|
||||
return `${year}-${month}`;
|
||||
}
|
||||
|
||||
export function getDay(date) {
|
||||
return moment(date).date();
|
||||
}
|
||||
|
||||
export function getDayOfWeekName(date) {
|
||||
const dayOfWeek = moment(date).days();
|
||||
return dateTimeConstants.allWeekDaysArray[dayOfWeek].name;
|
||||
}
|
||||
|
||||
export function getHour(date) {
|
||||
return moment(date).hour();
|
||||
}
|
||||
|
||||
export function getMinute(date) {
|
||||
return moment(date).minute();
|
||||
}
|
||||
|
||||
export function getSecond(date) {
|
||||
return moment(date).second();
|
||||
}
|
||||
|
||||
export function getUnixTimeBeforeUnixTime(unixTime, amount, unit) {
|
||||
return moment.unix(unixTime).subtract(amount, unit).unix();
|
||||
}
|
||||
|
||||
export function getUnixTimeAfterUnixTime(unixTime, amount, unit) {
|
||||
return moment.unix(unixTime).add(amount, unit).unix();
|
||||
}
|
||||
|
||||
export function getMinuteFirstUnixTime(date) {
|
||||
const datetime = moment(date);
|
||||
return datetime.set({ second: 0, millisecond: 0 }).unix();
|
||||
}
|
||||
|
||||
export function getMinuteLastUnixTime(date) {
|
||||
return moment.unix(getMinuteFirstUnixTime(date)).add(1, 'minutes').subtract(1, 'seconds').unix();
|
||||
}
|
||||
|
||||
export function getTodayFirstUnixTime() {
|
||||
return moment().set({ hour: 0, minute: 0, second: 0, millisecond: 0 }).unix();
|
||||
}
|
||||
|
||||
export function getTodayLastUnixTime() {
|
||||
return moment.unix(getTodayFirstUnixTime()).add(1, 'days').subtract(1, 'seconds').unix();
|
||||
}
|
||||
|
||||
export function getThisWeekFirstUnixTime(firstDayOfWeek) {
|
||||
const today = moment.unix(getTodayFirstUnixTime());
|
||||
|
||||
if (!isNumber(firstDayOfWeek)) {
|
||||
firstDayOfWeek = 0;
|
||||
}
|
||||
|
||||
let dayOfWeek = today.day() - firstDayOfWeek;
|
||||
|
||||
if (dayOfWeek < 0) {
|
||||
dayOfWeek += 7;
|
||||
}
|
||||
|
||||
return today.subtract(dayOfWeek, 'days').unix();
|
||||
}
|
||||
|
||||
export function getThisWeekLastUnixTime(firstDayOfWeek) {
|
||||
return moment.unix(getThisWeekFirstUnixTime(firstDayOfWeek)).add(7, 'days').subtract(1, 'seconds').unix();
|
||||
}
|
||||
|
||||
export function getThisMonthFirstUnixTime() {
|
||||
const today = moment.unix(getTodayFirstUnixTime());
|
||||
return today.subtract(today.date() - 1, 'days').unix();
|
||||
}
|
||||
|
||||
export function getThisMonthLastUnixTime() {
|
||||
return moment.unix(getThisMonthFirstUnixTime()).add(1, 'months').subtract(1, 'seconds').unix();
|
||||
}
|
||||
|
||||
export function getThisYearFirstUnixTime() {
|
||||
const today = moment.unix(getTodayFirstUnixTime());
|
||||
return today.subtract(today.dayOfYear() - 1, 'days').unix();
|
||||
}
|
||||
|
||||
export function getThisYearLastUnixTime() {
|
||||
return moment.unix(getThisYearFirstUnixTime()).add(1, 'years').subtract(1, 'seconds').unix();
|
||||
}
|
||||
|
||||
export function getShiftedDateRange(minTime, maxTime, scale) {
|
||||
const minDateTime = parseDateFromUnixTime(minTime).set({ second: 0, millisecond: 0 });
|
||||
const maxDateTime = parseDateFromUnixTime(maxTime).set({ second: 59, millisecond: 999 });
|
||||
|
||||
const firstDayOfMonth = minDateTime.clone().startOf('month');
|
||||
const lastDayOfMonth = maxDateTime.clone().endOf('month');
|
||||
|
||||
if (firstDayOfMonth.unix() === minDateTime.unix() && lastDayOfMonth.unix() === maxDateTime.unix()) {
|
||||
const months = getYear(maxDateTime) * 12 + getMonth(maxDateTime) - getYear(minDateTime) * 12 - getMonth(minDateTime) + 1;
|
||||
const newMinDateTime = minDateTime.add(months * scale, 'months');
|
||||
const newMaxDateTime = newMinDateTime.clone().add(months, 'months').subtract(1, 'seconds');
|
||||
|
||||
return {
|
||||
minTime: newMinDateTime.unix(),
|
||||
maxTime: newMaxDateTime.unix()
|
||||
};
|
||||
}
|
||||
|
||||
const range = (maxTime - minTime + 1) * scale;
|
||||
|
||||
return {
|
||||
minTime: minTime + range,
|
||||
maxTime: maxTime + range
|
||||
};
|
||||
}
|
||||
|
||||
export function getDateRangeByDateType(dateType, firstDayOfWeek) {
|
||||
let maxTime = 0;
|
||||
let minTime = 0;
|
||||
|
||||
if (dateType === dateTimeConstants.allDateRanges.All.type) { // All
|
||||
maxTime = 0;
|
||||
minTime = 0;
|
||||
} else if (dateType === dateTimeConstants.allDateRanges.Today.type) { // Today
|
||||
maxTime = getTodayLastUnixTime();
|
||||
minTime = getTodayFirstUnixTime();
|
||||
} else if (dateType === dateTimeConstants.allDateRanges.Yesterday.type) { // Yesterday
|
||||
maxTime = getUnixTimeBeforeUnixTime(getTodayLastUnixTime(), 1, 'days');
|
||||
minTime = getUnixTimeBeforeUnixTime(getTodayFirstUnixTime(), 1, 'days');
|
||||
} else if (dateType === dateTimeConstants.allDateRanges.LastSevenDays.type) { // Last 7 days
|
||||
maxTime = getTodayLastUnixTime();
|
||||
minTime = getUnixTimeBeforeUnixTime(getTodayFirstUnixTime(), 6, 'days');
|
||||
} else if (dateType === dateTimeConstants.allDateRanges.LastThirtyDays.type) { // Last 30 days
|
||||
maxTime = getTodayLastUnixTime();
|
||||
minTime = getUnixTimeBeforeUnixTime(getTodayFirstUnixTime(), 29, 'days');
|
||||
} else if (dateType === dateTimeConstants.allDateRanges.ThisWeek.type) { // This week
|
||||
maxTime = getThisWeekLastUnixTime(firstDayOfWeek);
|
||||
minTime = getThisWeekFirstUnixTime(firstDayOfWeek);
|
||||
} else if (dateType === dateTimeConstants.allDateRanges.LastWeek.type) { // Last week
|
||||
maxTime = getUnixTimeBeforeUnixTime(getThisWeekLastUnixTime(firstDayOfWeek), 7, 'days');
|
||||
minTime = getUnixTimeBeforeUnixTime(getThisWeekFirstUnixTime(firstDayOfWeek), 7, 'days');
|
||||
} else if (dateType === dateTimeConstants.allDateRanges.ThisMonth.type) { // This month
|
||||
maxTime = getThisMonthLastUnixTime();
|
||||
minTime = getThisMonthFirstUnixTime();
|
||||
} else if (dateType === dateTimeConstants.allDateRanges.LastMonth.type) { // Last month
|
||||
maxTime = getUnixTimeBeforeUnixTime(getThisMonthFirstUnixTime(), 1, 'seconds');
|
||||
minTime = getUnixTimeBeforeUnixTime(getThisMonthFirstUnixTime(), 1, 'months');
|
||||
} else if (dateType === dateTimeConstants.allDateRanges.ThisYear.type) { // This year
|
||||
maxTime = getThisYearLastUnixTime();
|
||||
minTime = getThisYearFirstUnixTime();
|
||||
} else if (dateType === dateTimeConstants.allDateRanges.LastYear.type) { // Last year
|
||||
maxTime = getUnixTimeBeforeUnixTime(getThisYearLastUnixTime(), 1, 'years');
|
||||
minTime = getUnixTimeBeforeUnixTime(getThisYearFirstUnixTime(), 1, 'years');
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
dateType: dateType,
|
||||
maxTime: maxTime,
|
||||
minTime: minTime
|
||||
};
|
||||
}
|
||||
|
||||
export function isDateRangeMatchFullYears(minTime, maxTime) {
|
||||
const minDateTime = parseDateFromUnixTime(minTime).set({ second: 0, millisecond: 0 });
|
||||
const maxDateTime = parseDateFromUnixTime(maxTime).set({ second: 59, millisecond: 999 });
|
||||
|
||||
const firstDayOfYear = minDateTime.clone().startOf('year');
|
||||
const lastDayOfYear = maxDateTime.clone().endOf('year');
|
||||
|
||||
return firstDayOfYear.unix() === minDateTime.unix() && lastDayOfYear.unix() === maxDateTime.unix();
|
||||
}
|
||||
|
||||
export function isDateRangeMatchFullMonths(minTime, maxTime) {
|
||||
const minDateTime = parseDateFromUnixTime(minTime).set({ second: 0, millisecond: 0 });
|
||||
const maxDateTime = parseDateFromUnixTime(maxTime).set({ second: 59, millisecond: 999 });
|
||||
|
||||
const firstDayOfMonth = minDateTime.clone().startOf('month');
|
||||
const lastDayOfMonth = maxDateTime.clone().endOf('month');
|
||||
|
||||
return firstDayOfMonth.unix() === minDateTime.unix() && lastDayOfMonth.unix() === maxDateTime.unix();
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
import {
|
||||
isFunction,
|
||||
isObject,
|
||||
isArray,
|
||||
isString,
|
||||
isNumber,
|
||||
isBoolean,
|
||||
isEquals,
|
||||
appendThousandsSeparator,
|
||||
formatPercent,
|
||||
limitText,
|
||||
base64encode,
|
||||
arrayBufferToString,
|
||||
stringToArrayBuffer,
|
||||
getNameByKeyValue,
|
||||
copyObjectTo,
|
||||
copyArrayTo,
|
||||
arrangeArrayWithNewStartIndex,
|
||||
} from './common.js'
|
||||
|
||||
import {
|
||||
getUtcOffsetMinutesByUtcOffset,
|
||||
getUtcOffsetByUtcOffsetMinutes,
|
||||
getTimezoneOffset,
|
||||
getTimezoneOffsetMinutes,
|
||||
getBrowserTimezoneOffsetMinutes,
|
||||
getLocalDatetimeFromUnixTime,
|
||||
getUnixTimeFromLocalDatetime,
|
||||
getActualUnixTimeForStore,
|
||||
getDummyUnixTimeForLocalUsage,
|
||||
getCurrentUnixTime,
|
||||
getCurrentDateTime,
|
||||
parseDateFromUnixTime,
|
||||
is24HourFormat,
|
||||
formatUnixTime,
|
||||
formatTime,
|
||||
getUnixTime,
|
||||
getYear,
|
||||
getMonth,
|
||||
getYearAndMonth,
|
||||
getDay,
|
||||
getDayOfWeekName,
|
||||
getHour,
|
||||
getMinute,
|
||||
getSecond,
|
||||
getUnixTimeBeforeUnixTime,
|
||||
getUnixTimeAfterUnixTime,
|
||||
getMinuteFirstUnixTime,
|
||||
getMinuteLastUnixTime,
|
||||
getTodayFirstUnixTime,
|
||||
getTodayLastUnixTime,
|
||||
getThisWeekFirstUnixTime,
|
||||
getThisWeekLastUnixTime,
|
||||
getThisMonthFirstUnixTime,
|
||||
getThisMonthLastUnixTime,
|
||||
getThisYearFirstUnixTime,
|
||||
getThisYearLastUnixTime,
|
||||
getShiftedDateRange,
|
||||
getDateRangeByDateType,
|
||||
isDateRangeMatchFullYears,
|
||||
isDateRangeMatchFullMonths,
|
||||
} from './datetime.js'
|
||||
|
||||
import {
|
||||
numericCurrencyToString,
|
||||
stringCurrencyToNumeric,
|
||||
getExchangedAmount,
|
||||
} from './currency.js'
|
||||
|
||||
import {
|
||||
generateRandomString,
|
||||
parseUserAgent,
|
||||
parseDeviceInfo,
|
||||
makeButtonCopyToClipboard,
|
||||
changeClipboardObjectText,
|
||||
} from './misc.js'
|
||||
|
||||
import {
|
||||
transactionTypeToCategoryType,
|
||||
categoryTypeToTransactionType,
|
||||
allVisibleTransactionCategories,
|
||||
} from './category.js'
|
||||
|
||||
import {
|
||||
getAccountCategoryInfo,
|
||||
getCategorizedAccounts,
|
||||
getVisibleCategorizedAccounts,
|
||||
getAllFilteredAccountsBalance,
|
||||
} from './account.js'
|
||||
|
||||
export default {
|
||||
// common.js
|
||||
isFunction,
|
||||
isObject,
|
||||
isArray,
|
||||
isString,
|
||||
isNumber,
|
||||
isBoolean,
|
||||
isEquals,
|
||||
appendThousandsSeparator,
|
||||
formatPercent,
|
||||
limitText,
|
||||
base64encode,
|
||||
arrayBufferToString,
|
||||
stringToArrayBuffer,
|
||||
getNameByKeyValue,
|
||||
copyObjectTo,
|
||||
copyArrayTo,
|
||||
arrangeArrayWithNewStartIndex,
|
||||
|
||||
// datetime.js
|
||||
getUtcOffsetMinutesByUtcOffset,
|
||||
getUtcOffsetByUtcOffsetMinutes,
|
||||
getTimezoneOffset,
|
||||
getTimezoneOffsetMinutes,
|
||||
getBrowserTimezoneOffsetMinutes,
|
||||
getLocalDatetimeFromUnixTime,
|
||||
getUnixTimeFromLocalDatetime,
|
||||
getActualUnixTimeForStore,
|
||||
getDummyUnixTimeForLocalUsage,
|
||||
getCurrentUnixTime,
|
||||
getCurrentDateTime,
|
||||
parseDateFromUnixTime,
|
||||
is24HourFormat,
|
||||
formatUnixTime,
|
||||
formatTime,
|
||||
getUnixTime,
|
||||
getYear,
|
||||
getMonth,
|
||||
getYearAndMonth,
|
||||
getDay,
|
||||
getDayOfWeekName,
|
||||
getHour,
|
||||
getMinute,
|
||||
getSecond,
|
||||
getUnixTimeBeforeUnixTime,
|
||||
getUnixTimeAfterUnixTime,
|
||||
getMinuteFirstUnixTime,
|
||||
getMinuteLastUnixTime,
|
||||
getTodayFirstUnixTime,
|
||||
getTodayLastUnixTime,
|
||||
getThisWeekFirstUnixTime,
|
||||
getThisWeekLastUnixTime,
|
||||
getThisMonthFirstUnixTime,
|
||||
getThisMonthLastUnixTime,
|
||||
getThisYearFirstUnixTime,
|
||||
getThisYearLastUnixTime,
|
||||
getShiftedDateRange,
|
||||
getDateRangeByDateType,
|
||||
isDateRangeMatchFullYears,
|
||||
isDateRangeMatchFullMonths,
|
||||
|
||||
// currency.js
|
||||
numericCurrencyToString,
|
||||
stringCurrencyToNumeric,
|
||||
getExchangedAmount,
|
||||
|
||||
// misc.js
|
||||
generateRandomString,
|
||||
parseUserAgent,
|
||||
parseDeviceInfo,
|
||||
makeButtonCopyToClipboard,
|
||||
changeClipboardObjectText,
|
||||
|
||||
// category.js
|
||||
transactionTypeToCategoryType,
|
||||
categoryTypeToTransactionType,
|
||||
allVisibleTransactionCategories,
|
||||
|
||||
// account.js
|
||||
getAccountCategoryInfo,
|
||||
getCategorizedAccounts,
|
||||
getVisibleCategorizedAccounts,
|
||||
getAllFilteredAccountsBalance,
|
||||
};
|
||||
@@ -0,0 +1,95 @@
|
||||
import Clipboard from 'clipboard';
|
||||
import CryptoJS from 'crypto-js';
|
||||
import uaParser from 'ua-parser-js';
|
||||
|
||||
export function generateRandomString() {
|
||||
const baseString = 'ebk_' + Math.round(new Date().getTime() / 1000) + '_' + Math.random();
|
||||
return CryptoJS.SHA256(baseString).toString();
|
||||
}
|
||||
|
||||
export function parseUserAgent(ua) {
|
||||
const uaParseRet = uaParser(ua);
|
||||
|
||||
return {
|
||||
device: {
|
||||
vendor: uaParseRet.device.vendor,
|
||||
model: uaParseRet.device.model,
|
||||
type: uaParseRet.device.type
|
||||
},
|
||||
os: {
|
||||
name: uaParseRet.os.name,
|
||||
version: uaParseRet.os.version
|
||||
},
|
||||
browser: {
|
||||
name: uaParseRet.browser.name,
|
||||
version: uaParseRet.browser.version
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function parseDeviceInfo(ua) {
|
||||
const uaInfo = parseUserAgent(ua);
|
||||
let result = '';
|
||||
|
||||
if (uaInfo.device.model) {
|
||||
result = uaInfo.device.model;
|
||||
} else if (uaInfo.os.name) {
|
||||
result = uaInfo.os.name;
|
||||
|
||||
if (uaInfo.os.version) {
|
||||
result += ' ' + uaInfo.os.version;
|
||||
}
|
||||
}
|
||||
|
||||
if (uaInfo.browser.name) {
|
||||
let browserInfo = uaInfo.browser.name;
|
||||
|
||||
if (uaInfo.browser.version) {
|
||||
browserInfo += ' ' + uaInfo.browser.version;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
result += ' (' + browserInfo + ')';
|
||||
} else {
|
||||
result = browserInfo;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
return 'Unknown Device';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export function makeButtonCopyToClipboard({ text, el, successCallback, errorCallback }) {
|
||||
const clipboard = new Clipboard(el, {
|
||||
text: function () {
|
||||
return text;
|
||||
}
|
||||
});
|
||||
|
||||
clipboard.on('success', (e) => {
|
||||
if (successCallback) {
|
||||
successCallback(e);
|
||||
}
|
||||
});
|
||||
|
||||
clipboard.on('error', (e) => {
|
||||
if (errorCallback) {
|
||||
errorCallback(e);
|
||||
}
|
||||
});
|
||||
|
||||
return clipboard;
|
||||
}
|
||||
|
||||
export function changeClipboardObjectText(clipboard, text) {
|
||||
if (!clipboard) {
|
||||
return;
|
||||
}
|
||||
|
||||
clipboard.text = function () {
|
||||
return text;
|
||||
};
|
||||
}
|
||||
-1079
File diff suppressed because it is too large
Load Diff
+11
-11
@@ -1,6 +1,6 @@
|
||||
import CBOR from 'cbor-js';
|
||||
import logger from './logger.js';
|
||||
import utils from './utils.js';
|
||||
import utilities from './utilities/index.js';
|
||||
|
||||
const publicKeyCredentialCreationOptionsBaseTemplate = {
|
||||
attestation: "none",
|
||||
@@ -28,7 +28,7 @@ const publicKeyCredentialRequestOptionsBaseTemplate = {
|
||||
function isSupported() {
|
||||
return !!window.PublicKeyCredential
|
||||
&& !!navigator.credentials
|
||||
&& utils.isFunction(window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable);
|
||||
&& utilities.isFunction(window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable);
|
||||
}
|
||||
|
||||
function isCompletelySupported() {
|
||||
@@ -52,17 +52,17 @@ function registerCredential({ username, secret }, { nickname }) {
|
||||
});
|
||||
}
|
||||
|
||||
const challenge = utils.generateRandomString();
|
||||
const challenge = utilities.generateRandomString();
|
||||
const userId = `${username}|${secret}`; // username 32bytes(max) + secret 24bytes = 56bytes(max)
|
||||
|
||||
const publicKeyCredentialCreationOptions = Object.assign({}, publicKeyCredentialCreationOptionsBaseTemplate, {
|
||||
challenge: utils.stringToArrayBuffer(challenge),
|
||||
challenge: utilities.stringToArrayBuffer(challenge),
|
||||
rp: {
|
||||
name: window.location.hostname,
|
||||
id: window.location.hostname
|
||||
},
|
||||
user: {
|
||||
id: utils.stringToArrayBuffer(userId),
|
||||
id: utilities.stringToArrayBuffer(userId),
|
||||
name: username,
|
||||
displayName: nickname
|
||||
}
|
||||
@@ -83,7 +83,7 @@ function registerCredential({ username, secret }, { nickname }) {
|
||||
if (rawCredential && rawCredential.rawId &&
|
||||
clientData && clientData.type === 'webauthn.create' && challengeFromClientData === challenge) {
|
||||
const ret = {
|
||||
id: utils.base64encode(rawCredential.rawId),
|
||||
id: utilities.base64encode(rawCredential.rawId),
|
||||
clientData: clientData,
|
||||
publicKey: publicKey,
|
||||
rawCredential: rawCredential
|
||||
@@ -133,12 +133,12 @@ function verifyCredential({ username }, credentialId) {
|
||||
});
|
||||
}
|
||||
|
||||
const challenge = utils.generateRandomString();
|
||||
const challenge = utilities.generateRandomString();
|
||||
const publicKeyCredentialRequestOptions = Object.assign({}, publicKeyCredentialRequestOptionsBaseTemplate, {
|
||||
challenge: utils.stringToArrayBuffer(challenge),
|
||||
challenge: utilities.stringToArrayBuffer(challenge),
|
||||
rpId: window.location.hostname
|
||||
});
|
||||
publicKeyCredentialRequestOptions.allowCredentials[0].id = utils.stringToArrayBuffer(atob(credentialId));
|
||||
publicKeyCredentialRequestOptions.allowCredentials[0].id = utilities.stringToArrayBuffer(atob(credentialId));
|
||||
|
||||
logger.debug('webauthn get options', publicKeyCredentialRequestOptions);
|
||||
|
||||
@@ -147,7 +147,7 @@ function verifyCredential({ username }, credentialId) {
|
||||
}).then(rawCredential => {
|
||||
const clientData = rawCredential ? parseClientData(rawCredential) : null;
|
||||
const challengeFromClientData = clientData && clientData.challenge ? atob(clientData.challenge) : null;
|
||||
const userIdParts = rawCredential && rawCredential.response && rawCredential.response.userHandle ? utils.arrayBufferToString(rawCredential.response.userHandle).split('|') : null;
|
||||
const userIdParts = rawCredential && rawCredential.response && rawCredential.response.userHandle ? utilities.arrayBufferToString(rawCredential.response.userHandle).split('|') : null;
|
||||
|
||||
logger.debug('webauthn get raw response', rawCredential);
|
||||
|
||||
@@ -155,7 +155,7 @@ function verifyCredential({ username }, credentialId) {
|
||||
clientData && clientData.type === 'webauthn.get' && challengeFromClientData === challenge &&
|
||||
userIdParts && userIdParts.length === 2 && userIdParts[0] === username) {
|
||||
const ret = {
|
||||
id: utils.base64encode(rawCredential.rawId),
|
||||
id: utilities.base64encode(rawCredential.rawId),
|
||||
userName: userIdParts[0],
|
||||
userSecret: userIdParts[1],
|
||||
clientData: clientData,
|
||||
|
||||
Reference in New Issue
Block a user