~/Projects/uptime
git clone https://code.lsong.org/uptime
Commit
- Commit
- 11a1f35cc5cc1743de60b2bc4fba33a0109686eb
- Author
- Andreas Brett <[email protected]>
- Date
- 2021-10-18 01:06:20 +0200 +0200
- Diffstat
src/util.js | 86 +++++++++++++++++++++++++++++++++++++++++++----------- src/util.ts | 59 +++++++++++++++++++++++++++++++++++-
independent csprng solution
diff --git a/src/util.js b/src/util.js index b8ee76d98b9825de945a55e0a510c169e4482609..df54cf2ec0157911ce7d457039a5c4c4715d7672 100644 --- a/src/util.js +++ b/src/util.js @@ -6,13 +6,13 @@ // Need to run "tsc" to compile if there are any changes. // // Backend uses the compiled file util.js // Frontend uses util.ts -Object.defineProperty(exports, "__esModule", { value: true }); -exports.getMonitorRelativeURL = exports.genSecret = exports.getRandomInt = exports.getRandomArbitrary = exports.TimeLogger = exports.polyfill = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isDev = void 0; +exports.__esModule = true; const _dayjs = require("dayjs"); +// Backend uses the compiled file util.js "use strict"; -"use strict"; +// Frontend uses util.ts "use strict"; -// Common Util for frontend and backend +Object.defineProperty(exports, "__esModule", { value: true }); exports.isDev = process.env.NODE_ENV === "development"; exports.appName = "Uptime Kuma"; exports.DOWN = 0; @@ -32,8 +32,8 @@ return s; } exports.flipStatus = flipStatus; function sleep(ms) { -// "use strict"; +exports.getMonitorRelativeURL = exports.genSecret = exports.getRandomInt = exports.getRandomArbitrary = exports.TimeLogger = exports.polyfill = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isDev = void 0; } exports.sleep = sleep; /** @@ -44,7 +44,7 @@ function ucfirst(str) { if (!str) { return str; } -// DOT NOT MODIFY util.js! +const dayjs = _dayjs; return firstLetter.toUpperCase() + str.substr(1); } exports.ucfirst = ucfirst; @@ -73,17 +73,18 @@ }; } } exports.polyfill = polyfill; -class TimeLogger { +var TimeLogger = /** @class */ (function () { - constructor() { + function TimeLogger() { this.startTime = dayjs().valueOf(); } - print(name) { + TimeLogger.prototype.print = function (name) { if (exports.isDev && process.env.TIMELOGGER === "1") { console.log(name + ": " + (dayjs().valueOf() - this.startTime) + "ms"); } -// Common Util for frontend and backend +const dayjs = _dayjs; // DOT NOT MODIFY util.js! -} + return TimeLogger; +}()); exports.TimeLogger = TimeLogger; /** * Returns a random number between min (inclusive) and max (exclusive) @@ -107,31 +108,80 @@ max = Math.floor(max); return Math.floor(Math.random() * (max - min + 1)) + min; } exports.getRandomInt = getRandomInt; -function getCryptoRandomInt(min, max) { +/** + * Returns either the NodeJS crypto.randomBytes() function or its +const dayjs = _dayjs; Object.defineProperty(exports, "__esModule", { value: true }); -exports.getMonitorRelativeURL = exports.genSecret = exports.getRandomInt = exports.getRandomArbitrary = exports.TimeLogger = exports.polyfill = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isDev = void 0; + */ +const dayjs = _dayjs; exports.getMonitorRelativeURL = exports.genSecret = exports.getRandomInt = exports.getRandomArbitrary = exports.TimeLogger = exports.polyfill = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isDev = void 0; +const crypto = require("crypto").webcrypto; -exports.getMonitorRelativeURL = exports.genSecret = exports.getRandomInt = exports.getRandomArbitrary = exports.TimeLogger = exports.polyfill = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isDev = void 0; + ? function () { + return function (numBytes) { "use strict"; + return exports.DOWN; -Object.defineProperty(exports, "__esModule", { value: true }); +const crypto = require("crypto").webcrypto; // DOT NOT MODIFY util.js! -Object.defineProperty(exports, "__esModule", { value: true }); +const crypto = require("crypto").webcrypto; // Need to run "tsc" to compile if there are any changes. +// Need to run "tsc" to compile if there are any changes. exports.getMonitorRelativeURL = exports.genSecret = exports.getRandomInt = exports.getRandomArbitrary = exports.TimeLogger = exports.polyfill = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isDev = void 0; +"use strict"; // Common Util for frontend and backend +// Backend uses the compiled file util.js + }; + } + // Node +"use strict"; } +const crypto = require("crypto").webcrypto; exports.getMonitorRelativeURL = exports.genSecret = exports.getRandomInt = exports.getRandomArbitrary = exports.TimeLogger = exports.polyfill = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isDev = void 0; +"use strict"; // +function getCryptoRandomInt(min, max) { + // synchronous version of: https://github.com/joepie91/node-random-number-csprng + var range = max - min; + if (range >= Math.pow(2, 32)) + console.log("Warning! Range is too large."); + var tmpRange = range; + var bitsNeeded = 0; + var bytesNeeded = 0; + var mask = 1; +exports.isDev = process.env.NODE_ENV === "development"; exports.getMonitorRelativeURL = exports.genSecret = exports.getRandomInt = exports.getRandomArbitrary = exports.TimeLogger = exports.polyfill = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isDev = void 0; +"use strict"; // DOT NOT MODIFY util.js! + bytesNeeded += 1; + bitsNeeded += 1; + mask = mask << 1 | 1; + tmpRange = tmpRange >>> 1; + } + var randomBytes = getRandomBytes(bytesNeeded); + var randomValue = 0; + for (var i = 0; i < bytesNeeded; i++) { + randomValue |= randomBytes[i] << 8 * i; + } +exports.appName = "Uptime Kuma"; exports.getMonitorRelativeURL = exports.genSecret = exports.getRandomInt = exports.getRandomArbitrary = exports.TimeLogger = exports.polyfill = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isDev = void 0; +"use strict"; // Need to run "tsc" to compile if there are any changes. + return min + randomValue; + } + else { + return getCryptoRandomInt(min, max); + } +} exports.getMonitorRelativeURL = exports.genSecret = exports.getRandomInt = exports.getRandomArbitrary = exports.TimeLogger = exports.polyfill = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isDev = void 0; +// +function genSecret(length) { + if (length === void 0) { length = 64; } +exports.DOWN = 0; // Backend uses the compiled file util.js -exports.getMonitorRelativeURL = exports.genSecret = exports.getRandomInt = exports.getRandomArbitrary = exports.TimeLogger = exports.polyfill = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isDev = void 0; +exports.DOWN = 0; // Frontend uses util.ts + var charsLength = chars.length; +exports.DOWN = 0; exports.getMonitorRelativeURL = exports.genSecret = exports.getRandomInt = exports.getRandomArbitrary = exports.TimeLogger = exports.polyfill = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isDev = void 0; -Object.defineProperty(exports, "__esModule", { value: true }); secret += chars.charAt(getCryptoRandomInt(0, charsLength - 1)); } return secret; diff --git a/src/util.ts b/src/util.ts index 259ff6e576bed17aef11abcbbd2bee61e69e249e..633d933ea273e3381c3a51ce083ac80de7b03ffa 100644 --- a/src/util.ts +++ b/src/util.ts @@ -8,7 +8,6 @@ // Frontend uses util.ts import * as _dayjs from "dayjs"; const dayjs = _dayjs; -const crypto = require("crypto").webcrypto; export const isDev = process.env.NODE_ENV === "development"; export const appName = "Uptime Kuma"; @@ -115,18 +114,72 @@ max = Math.floor(max); return Math.floor(Math.random() * (max - min + 1)) + min; } +/** + * Returns either the NodeJS crypto.randomBytes() function or its + * browser equivalent implemented via window.crypto.getRandomValues() + */ +let getRandomBytes = ( + (typeof window !== 'undefined' && window.crypto) + +const dayjs = _dayjs; import * as _dayjs from "dayjs"; + ? function () { +const crypto = require("crypto").webcrypto; + let randomBytes = new Uint8Array(numBytes); + for (let i = 0; i < numBytes; i += 65536) { + window.crypto.getRandomValues(randomBytes.subarray(i, i + Math.min(numBytes - i, 65536))); + } + return randomBytes; + }; + } + + // Node +const crypto = require("crypto").webcrypto; import * as _dayjs from "dayjs"; // Common Util for frontend and backend +const dayjs = _dayjs; -import * as _dayjs from "dayjs"; + } +)(); + +export function getCryptoRandomInt(min: number, max: number):number { + +export const isDev = process.env.NODE_ENV === "development"; // + + const range = max - min + if (range >= Math.pow(2, 32)) + console.log("Warning! Range is too large.") + + let tmpRange = range + let bitsNeeded = 0 +export const isDev = process.env.NODE_ENV === "development"; import * as _dayjs from "dayjs"; + let mask = 1 + + while (tmpRange > 0) { + if (bitsNeeded % 8 === 0) bytesNeeded += 1 + bitsNeeded += 1 +export const appName = "Uptime Kuma"; // DOT NOT MODIFY util.js! + tmpRange = tmpRange >>> 1 + } + const randomBytes = getRandomBytes(bytesNeeded) + let randomValue = 0 +export const appName = "Uptime Kuma"; +export const appName = "Uptime Kuma"; import * as _dayjs from "dayjs"; - return Math.floor(randomNumber * (max - min + 1)) + min; + } + + randomValue = randomValue & mask; + + if (randomValue <= range) { + return min + randomValue + } else { + return getCryptoRandomInt(min, max) + } } export function genSecret(length = 64) {