generate-password-lite 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -2
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +1 -2
- package/package.json +2 -3
- package/dist/index.cjs.map +0 -7
- package/dist/index.mjs.map +0 -7
- package/src/index.ts +0 -22
- package/src/lib/check-options-error.ts +0 -52
- package/src/lib/generate-random-number.ts +0 -48
- package/src/lib/password-generator.ts +0 -92
- package/src/lib/process-options.ts +0 -34
- package/src/lib/shuffle-string.ts +0 -21
- package/src/types.ts +0 -57
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* generate-password-lite v1.1.
|
|
2
|
+
* generate-password-lite v1.1.1
|
|
3
3
|
* Tiny, dependency-free, cryptographically secure password generator for JavaScript and TypeScript projects.
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
@@ -199,4 +199,3 @@ var index_default = GeneratePassword;
|
|
|
199
199
|
0 && (module.exports = {
|
|
200
200
|
GeneratePassword
|
|
201
201
|
});
|
|
202
|
-
//# sourceMappingURL=index.cjs.map
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.mts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* generate-password-lite v1.1.
|
|
2
|
+
* generate-password-lite v1.1.1
|
|
3
3
|
* Tiny, dependency-free, cryptographically secure password generator for JavaScript and TypeScript projects.
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
@@ -173,4 +173,3 @@ export {
|
|
|
173
173
|
GeneratePassword,
|
|
174
174
|
index_default as default
|
|
175
175
|
};
|
|
176
|
-
//# sourceMappingURL=index.mjs.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "generate-password-lite",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Tiny, dependency-free, cryptographically secure password generator for JavaScript and TypeScript projects.",
|
|
6
6
|
"author": "Ahmad Joya <joya.abn@gmail.com>",
|
|
@@ -24,8 +24,7 @@
|
|
|
24
24
|
"./package.json": "./package.json"
|
|
25
25
|
},
|
|
26
26
|
"files": [
|
|
27
|
-
"dist"
|
|
28
|
-
"src"
|
|
27
|
+
"dist"
|
|
29
28
|
],
|
|
30
29
|
"engines": {
|
|
31
30
|
"node": ">=18"
|
package/dist/index.cjs.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/index.ts", "../src/lib/generate-random-number.ts", "../src/lib/shuffle-string.ts", "../src/lib/password-generator.ts", "../src/lib/check-options-error.ts", "../src/lib/process-options.ts"],
|
|
4
|
-
"sourcesContent": ["import { generatePswd } from './lib/password-generator'\nimport { checkError } from './lib/check-options-error'\nimport { processOption } from './lib/process-options'\nimport { GenerateOptions } from './types'\n\n/**\n * Generates a random password using a cryptographically secure random source.\n *\n * @param options - Optional overrides. Every unset option falls back to its\n * documented default.\n * @returns The generated password.\n */\nfunction GeneratePassword(options: GenerateOptions = {}): string {\n const resolved = processOption(options)\n\n checkError(resolved)\n\n return generatePswd(resolved)\n}\n\nexport { GeneratePassword, type GenerateOptions }\nexport default GeneratePassword\n", "/**\n * Number of distinct values a Uint32 can hold.\n */\nconst UINT32_RANGE = 0x100000000\n\nconst getWebCrypto = (): Crypto => {\n const webCrypto = globalThis.crypto\n\n if (!webCrypto || typeof webCrypto.getRandomValues !== 'function') {\n throw new Error(\n 'generate-password-lite: no Web Crypto implementation found. ' +\n 'A secure random source is required to generate passwords. ' +\n 'Use Node.js 18+, a modern browser, or polyfill `globalThis.crypto`.'\n )\n }\n\n return webCrypto\n}\n\n/**\n * Returns a cryptographically secure integer in the range [0, upperLimit).\n *\n * Uses rejection sampling so that every value is equally likely. Taking a\n * plain `random % upperLimit` would bias the low end of the range whenever\n * `upperLimit` is not a power of two.\n */\nexport const generateRandomNumbers = (upperLimit: number): number => {\n if (!Number.isInteger(upperLimit) || upperLimit <= 0) {\n throw new RangeError(\n `generate-password-lite: upperLimit must be a positive integer, received ${upperLimit}.`\n )\n }\n\n const webCrypto = getWebCrypto()\n const buffer = new Uint32Array(1)\n\n // Largest multiple of upperLimit that fits in the Uint32 range. Draws at or\n // above this cutoff are discarded rather than folded back into the range.\n const cutoff = Math.floor(UINT32_RANGE / upperLimit) * upperLimit\n\n let value: number\n do {\n webCrypto.getRandomValues(buffer)\n value = buffer[0]!\n } while (value >= cutoff)\n\n return value % upperLimit\n}\n", "import { generateRandomNumbers } from './generate-random-number'\n\n/**\n * Fisher-Yates shuffle backed by the same cryptographically secure source\n * used to pick the characters themselves.\n *\n * Spreads across code points rather than UTF-16 units so that a surrogate\n * pair supplied through `exclude` handling is never split in half.\n */\nexport const shuffleString = (str: string): string => {\n const chars = [...str]\n\n for (let i = chars.length - 1; i > 0; i--) {\n const j = generateRandomNumbers(i + 1)\n const tmp = chars[i]!\n chars[i] = chars[j]!\n chars[j] = tmp\n }\n\n return chars.join('')\n}\n", "import { generateRandomNumbers } from './generate-random-number'\nimport { shuffleString } from './shuffle-string'\nimport { ResolvedOptions } from '../types'\n\nconst LOWERCASE_CHARS = 'abcdefghijklmnopqrstuvwxyz'\nconst UPPERCASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'\nconst NUMBER_CHARS = '0123456789'\nconst SYMBOL_CHARS = \"!#$%&'()*+,-./:;<=>?@[]^_{|}~\"\n\n/**\n * Drops every excluded character. `String.replace` with a string pattern only\n * removes the first match, so the exclusion is done with a set instead.\n */\nconst removeExceptions = (str: string, exclude: string): string => {\n if (!exclude) return str\n\n const banned = new Set([...exclude])\n return [...str].filter(char => !banned.has(char)).join('')\n}\n\n/**\n * Picks `count` characters from `pool`. Throws when the caller asked for\n * guaranteed characters out of a pool that `exclude` emptied.\n */\nconst pickFrom = (pool: string, count: number, name: string): string => {\n if (count === 0) return ''\n\n if (pool.length === 0) {\n throw new Error(\n `generate-password-lite: \\`exclude\\` removed every ${name} character, but \\`minLength${name[0]!.toUpperCase()}${name.slice(1)}\\` is ${count}.`\n )\n }\n\n let picked = ''\n for (let i = 0; i < count; i++) {\n picked += pool.charAt(generateRandomNumbers(pool.length))\n }\n return picked\n}\n\nexport const generatePswd = (options: ResolvedOptions): string => {\n const {\n length,\n lowercase,\n uppercase,\n numbers,\n symbols,\n minLengthLowercase,\n minLengthUppercase,\n minLengthNumbers,\n minLengthSymbols,\n exclude,\n } = options\n\n const lowercaseChar = removeExceptions(LOWERCASE_CHARS, exclude)\n const uppercaseChar = removeExceptions(UPPERCASE_CHARS, exclude)\n const numberChar = removeExceptions(NUMBER_CHARS, exclude)\n const symbolChar = removeExceptions(SYMBOL_CHARS, exclude)\n\n // Characters that must appear, so that the password satisfies every\n // `minLength*` the caller asked for.\n const guaranteed =\n pickFrom(lowercaseChar, minLengthLowercase, 'lowercase') +\n pickFrom(uppercaseChar, minLengthUppercase, 'uppercase') +\n pickFrom(numberChar, minLengthNumbers, 'numbers') +\n pickFrom(symbolChar, minLengthSymbols, 'symbols')\n\n // Every character the enabled classes still allow after exclusions.\n const characterPool =\n (lowercase ? lowercaseChar : '') +\n (uppercase ? uppercaseChar : '') +\n (numbers ? numberChar : '') +\n (symbols ? symbolChar : '')\n\n const remaining = length - guaranteed.length\n\n if (remaining > 0 && characterPool.length === 0) {\n throw new Error(\n 'generate-password-lite: `exclude` removed every character of every enabled class. No valid characters to generate the password from.'\n )\n }\n\n let filler = ''\n for (let i = 0; i < remaining; i++) {\n filler += characterPool.charAt(generateRandomNumbers(characterPool.length))\n }\n\n // Shuffle the whole password, not just the guaranteed part. Shuffling only\n // the guaranteed characters would pin them to the leading positions and make\n // the layout of the password predictable.\n return shuffleString(guaranteed + filler)\n}\n", "import { ResolvedOptions } from '../types'\n\nconst assertCount = (value: number, name: string) => {\n if (!Number.isInteger(value) || value < 0) {\n throw new Error(\n `generate-password-lite: \\`${name}\\` must be a non-negative integer, received ${value}.`\n )\n }\n}\n\nexport const checkError = (options: ResolvedOptions) => {\n const {\n length,\n lowercase,\n uppercase,\n numbers,\n symbols,\n minLengthLowercase,\n minLengthUppercase,\n minLengthNumbers,\n minLengthSymbols,\n } = options\n\n if (!Number.isInteger(length) || length < 1) {\n throw new Error(\n `generate-password-lite: \\`length\\` must be a positive integer, received ${length}.`\n )\n }\n\n assertCount(minLengthLowercase, 'minLengthLowercase')\n assertCount(minLengthUppercase, 'minLengthUppercase')\n assertCount(minLengthNumbers, 'minLengthNumbers')\n assertCount(minLengthSymbols, 'minLengthSymbols')\n\n // Lowercase, uppercase, numbers and symbols have all been turned off, so\n // there is no character class left to build a password from.\n if (!lowercase && !uppercase && !numbers && !symbols) {\n throw new Error(\n 'generate-password-lite: `lowercase`, `uppercase`, `numbers` and `symbols` are all false. No valid characters to generate the password from.'\n )\n }\n\n // The guaranteed characters alone would already overflow the password.\n const minimumTotal =\n minLengthLowercase + minLengthUppercase + minLengthNumbers + minLengthSymbols\n\n if (minimumTotal > length) {\n throw new Error(\n `generate-password-lite: the sum of the minimum character counts (${minimumTotal}) is greater than \\`length\\` (${length}).`\n )\n }\n}\n", "import { GenerateOptions, ResolvedOptions } from '../types'\n\nconst withDefault = <T>(value: T | undefined, fallback: T): T =>\n typeof value === 'undefined' ? fallback : value\n\n/**\n * Fills in every unset option. Returns a new object so that the caller's\n * options are never mutated.\n */\nexport const processOption = (options: GenerateOptions): ResolvedOptions => {\n const lowercase = withDefault(options.lowercase, true)\n const uppercase = withDefault(options.uppercase, true)\n const numbers = withDefault(options.numbers, true)\n const symbols = withDefault(options.symbols, false)\n\n // A disabled character class can never contribute a minimum, regardless of\n // what the caller passed in.\n return {\n length: withDefault(options.length, 10),\n lowercase,\n uppercase,\n numbers,\n symbols,\n exclude: withDefault(options.exclude, ''),\n minLengthLowercase: lowercase\n ? withDefault(options.minLengthLowercase, 1)\n : 0,\n minLengthUppercase: uppercase\n ? withDefault(options.minLengthUppercase, 1)\n : 0,\n minLengthNumbers: numbers ? withDefault(options.minLengthNumbers, 1) : 0,\n minLengthSymbols: symbols ? withDefault(options.minLengthSymbols, 1) : 0,\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/index.mjs.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/lib/generate-random-number.ts", "../src/lib/shuffle-string.ts", "../src/lib/password-generator.ts", "../src/lib/check-options-error.ts", "../src/lib/process-options.ts", "../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Number of distinct values a Uint32 can hold.\n */\nconst UINT32_RANGE = 0x100000000\n\nconst getWebCrypto = (): Crypto => {\n const webCrypto = globalThis.crypto\n\n if (!webCrypto || typeof webCrypto.getRandomValues !== 'function') {\n throw new Error(\n 'generate-password-lite: no Web Crypto implementation found. ' +\n 'A secure random source is required to generate passwords. ' +\n 'Use Node.js 18+, a modern browser, or polyfill `globalThis.crypto`.'\n )\n }\n\n return webCrypto\n}\n\n/**\n * Returns a cryptographically secure integer in the range [0, upperLimit).\n *\n * Uses rejection sampling so that every value is equally likely. Taking a\n * plain `random % upperLimit` would bias the low end of the range whenever\n * `upperLimit` is not a power of two.\n */\nexport const generateRandomNumbers = (upperLimit: number): number => {\n if (!Number.isInteger(upperLimit) || upperLimit <= 0) {\n throw new RangeError(\n `generate-password-lite: upperLimit must be a positive integer, received ${upperLimit}.`\n )\n }\n\n const webCrypto = getWebCrypto()\n const buffer = new Uint32Array(1)\n\n // Largest multiple of upperLimit that fits in the Uint32 range. Draws at or\n // above this cutoff are discarded rather than folded back into the range.\n const cutoff = Math.floor(UINT32_RANGE / upperLimit) * upperLimit\n\n let value: number\n do {\n webCrypto.getRandomValues(buffer)\n value = buffer[0]!\n } while (value >= cutoff)\n\n return value % upperLimit\n}\n", "import { generateRandomNumbers } from './generate-random-number'\n\n/**\n * Fisher-Yates shuffle backed by the same cryptographically secure source\n * used to pick the characters themselves.\n *\n * Spreads across code points rather than UTF-16 units so that a surrogate\n * pair supplied through `exclude` handling is never split in half.\n */\nexport const shuffleString = (str: string): string => {\n const chars = [...str]\n\n for (let i = chars.length - 1; i > 0; i--) {\n const j = generateRandomNumbers(i + 1)\n const tmp = chars[i]!\n chars[i] = chars[j]!\n chars[j] = tmp\n }\n\n return chars.join('')\n}\n", "import { generateRandomNumbers } from './generate-random-number'\nimport { shuffleString } from './shuffle-string'\nimport { ResolvedOptions } from '../types'\n\nconst LOWERCASE_CHARS = 'abcdefghijklmnopqrstuvwxyz'\nconst UPPERCASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'\nconst NUMBER_CHARS = '0123456789'\nconst SYMBOL_CHARS = \"!#$%&'()*+,-./:;<=>?@[]^_{|}~\"\n\n/**\n * Drops every excluded character. `String.replace` with a string pattern only\n * removes the first match, so the exclusion is done with a set instead.\n */\nconst removeExceptions = (str: string, exclude: string): string => {\n if (!exclude) return str\n\n const banned = new Set([...exclude])\n return [...str].filter(char => !banned.has(char)).join('')\n}\n\n/**\n * Picks `count` characters from `pool`. Throws when the caller asked for\n * guaranteed characters out of a pool that `exclude` emptied.\n */\nconst pickFrom = (pool: string, count: number, name: string): string => {\n if (count === 0) return ''\n\n if (pool.length === 0) {\n throw new Error(\n `generate-password-lite: \\`exclude\\` removed every ${name} character, but \\`minLength${name[0]!.toUpperCase()}${name.slice(1)}\\` is ${count}.`\n )\n }\n\n let picked = ''\n for (let i = 0; i < count; i++) {\n picked += pool.charAt(generateRandomNumbers(pool.length))\n }\n return picked\n}\n\nexport const generatePswd = (options: ResolvedOptions): string => {\n const {\n length,\n lowercase,\n uppercase,\n numbers,\n symbols,\n minLengthLowercase,\n minLengthUppercase,\n minLengthNumbers,\n minLengthSymbols,\n exclude,\n } = options\n\n const lowercaseChar = removeExceptions(LOWERCASE_CHARS, exclude)\n const uppercaseChar = removeExceptions(UPPERCASE_CHARS, exclude)\n const numberChar = removeExceptions(NUMBER_CHARS, exclude)\n const symbolChar = removeExceptions(SYMBOL_CHARS, exclude)\n\n // Characters that must appear, so that the password satisfies every\n // `minLength*` the caller asked for.\n const guaranteed =\n pickFrom(lowercaseChar, minLengthLowercase, 'lowercase') +\n pickFrom(uppercaseChar, minLengthUppercase, 'uppercase') +\n pickFrom(numberChar, minLengthNumbers, 'numbers') +\n pickFrom(symbolChar, minLengthSymbols, 'symbols')\n\n // Every character the enabled classes still allow after exclusions.\n const characterPool =\n (lowercase ? lowercaseChar : '') +\n (uppercase ? uppercaseChar : '') +\n (numbers ? numberChar : '') +\n (symbols ? symbolChar : '')\n\n const remaining = length - guaranteed.length\n\n if (remaining > 0 && characterPool.length === 0) {\n throw new Error(\n 'generate-password-lite: `exclude` removed every character of every enabled class. No valid characters to generate the password from.'\n )\n }\n\n let filler = ''\n for (let i = 0; i < remaining; i++) {\n filler += characterPool.charAt(generateRandomNumbers(characterPool.length))\n }\n\n // Shuffle the whole password, not just the guaranteed part. Shuffling only\n // the guaranteed characters would pin them to the leading positions and make\n // the layout of the password predictable.\n return shuffleString(guaranteed + filler)\n}\n", "import { ResolvedOptions } from '../types'\n\nconst assertCount = (value: number, name: string) => {\n if (!Number.isInteger(value) || value < 0) {\n throw new Error(\n `generate-password-lite: \\`${name}\\` must be a non-negative integer, received ${value}.`\n )\n }\n}\n\nexport const checkError = (options: ResolvedOptions) => {\n const {\n length,\n lowercase,\n uppercase,\n numbers,\n symbols,\n minLengthLowercase,\n minLengthUppercase,\n minLengthNumbers,\n minLengthSymbols,\n } = options\n\n if (!Number.isInteger(length) || length < 1) {\n throw new Error(\n `generate-password-lite: \\`length\\` must be a positive integer, received ${length}.`\n )\n }\n\n assertCount(minLengthLowercase, 'minLengthLowercase')\n assertCount(minLengthUppercase, 'minLengthUppercase')\n assertCount(minLengthNumbers, 'minLengthNumbers')\n assertCount(minLengthSymbols, 'minLengthSymbols')\n\n // Lowercase, uppercase, numbers and symbols have all been turned off, so\n // there is no character class left to build a password from.\n if (!lowercase && !uppercase && !numbers && !symbols) {\n throw new Error(\n 'generate-password-lite: `lowercase`, `uppercase`, `numbers` and `symbols` are all false. No valid characters to generate the password from.'\n )\n }\n\n // The guaranteed characters alone would already overflow the password.\n const minimumTotal =\n minLengthLowercase + minLengthUppercase + minLengthNumbers + minLengthSymbols\n\n if (minimumTotal > length) {\n throw new Error(\n `generate-password-lite: the sum of the minimum character counts (${minimumTotal}) is greater than \\`length\\` (${length}).`\n )\n }\n}\n", "import { GenerateOptions, ResolvedOptions } from '../types'\n\nconst withDefault = <T>(value: T | undefined, fallback: T): T =>\n typeof value === 'undefined' ? fallback : value\n\n/**\n * Fills in every unset option. Returns a new object so that the caller's\n * options are never mutated.\n */\nexport const processOption = (options: GenerateOptions): ResolvedOptions => {\n const lowercase = withDefault(options.lowercase, true)\n const uppercase = withDefault(options.uppercase, true)\n const numbers = withDefault(options.numbers, true)\n const symbols = withDefault(options.symbols, false)\n\n // A disabled character class can never contribute a minimum, regardless of\n // what the caller passed in.\n return {\n length: withDefault(options.length, 10),\n lowercase,\n uppercase,\n numbers,\n symbols,\n exclude: withDefault(options.exclude, ''),\n minLengthLowercase: lowercase\n ? withDefault(options.minLengthLowercase, 1)\n : 0,\n minLengthUppercase: uppercase\n ? withDefault(options.minLengthUppercase, 1)\n : 0,\n minLengthNumbers: numbers ? withDefault(options.minLengthNumbers, 1) : 0,\n minLengthSymbols: symbols ? withDefault(options.minLengthSymbols, 1) : 0,\n }\n}\n", "import { generatePswd } from './lib/password-generator'\nimport { checkError } from './lib/check-options-error'\nimport { processOption } from './lib/process-options'\nimport { GenerateOptions } from './types'\n\n/**\n * Generates a random password using a cryptographically secure random source.\n *\n * @param options - Optional overrides. Every unset option falls back to its\n * documented default.\n * @returns The generated password.\n */\nfunction GeneratePassword(options: GenerateOptions = {}): string {\n const resolved = processOption(options)\n\n checkError(resolved)\n\n return generatePswd(resolved)\n}\n\nexport { GeneratePassword, type GenerateOptions }\nexport default GeneratePassword\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { generatePswd } from './lib/password-generator'
|
|
2
|
-
import { checkError } from './lib/check-options-error'
|
|
3
|
-
import { processOption } from './lib/process-options'
|
|
4
|
-
import { GenerateOptions } from './types'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Generates a random password using a cryptographically secure random source.
|
|
8
|
-
*
|
|
9
|
-
* @param options - Optional overrides. Every unset option falls back to its
|
|
10
|
-
* documented default.
|
|
11
|
-
* @returns The generated password.
|
|
12
|
-
*/
|
|
13
|
-
function GeneratePassword(options: GenerateOptions = {}): string {
|
|
14
|
-
const resolved = processOption(options)
|
|
15
|
-
|
|
16
|
-
checkError(resolved)
|
|
17
|
-
|
|
18
|
-
return generatePswd(resolved)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export { GeneratePassword, type GenerateOptions }
|
|
22
|
-
export default GeneratePassword
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { ResolvedOptions } from '../types'
|
|
2
|
-
|
|
3
|
-
const assertCount = (value: number, name: string) => {
|
|
4
|
-
if (!Number.isInteger(value) || value < 0) {
|
|
5
|
-
throw new Error(
|
|
6
|
-
`generate-password-lite: \`${name}\` must be a non-negative integer, received ${value}.`
|
|
7
|
-
)
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const checkError = (options: ResolvedOptions) => {
|
|
12
|
-
const {
|
|
13
|
-
length,
|
|
14
|
-
lowercase,
|
|
15
|
-
uppercase,
|
|
16
|
-
numbers,
|
|
17
|
-
symbols,
|
|
18
|
-
minLengthLowercase,
|
|
19
|
-
minLengthUppercase,
|
|
20
|
-
minLengthNumbers,
|
|
21
|
-
minLengthSymbols,
|
|
22
|
-
} = options
|
|
23
|
-
|
|
24
|
-
if (!Number.isInteger(length) || length < 1) {
|
|
25
|
-
throw new Error(
|
|
26
|
-
`generate-password-lite: \`length\` must be a positive integer, received ${length}.`
|
|
27
|
-
)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
assertCount(minLengthLowercase, 'minLengthLowercase')
|
|
31
|
-
assertCount(minLengthUppercase, 'minLengthUppercase')
|
|
32
|
-
assertCount(minLengthNumbers, 'minLengthNumbers')
|
|
33
|
-
assertCount(minLengthSymbols, 'minLengthSymbols')
|
|
34
|
-
|
|
35
|
-
// Lowercase, uppercase, numbers and symbols have all been turned off, so
|
|
36
|
-
// there is no character class left to build a password from.
|
|
37
|
-
if (!lowercase && !uppercase && !numbers && !symbols) {
|
|
38
|
-
throw new Error(
|
|
39
|
-
'generate-password-lite: `lowercase`, `uppercase`, `numbers` and `symbols` are all false. No valid characters to generate the password from.'
|
|
40
|
-
)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// The guaranteed characters alone would already overflow the password.
|
|
44
|
-
const minimumTotal =
|
|
45
|
-
minLengthLowercase + minLengthUppercase + minLengthNumbers + minLengthSymbols
|
|
46
|
-
|
|
47
|
-
if (minimumTotal > length) {
|
|
48
|
-
throw new Error(
|
|
49
|
-
`generate-password-lite: the sum of the minimum character counts (${minimumTotal}) is greater than \`length\` (${length}).`
|
|
50
|
-
)
|
|
51
|
-
}
|
|
52
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Number of distinct values a Uint32 can hold.
|
|
3
|
-
*/
|
|
4
|
-
const UINT32_RANGE = 0x100000000
|
|
5
|
-
|
|
6
|
-
const getWebCrypto = (): Crypto => {
|
|
7
|
-
const webCrypto = globalThis.crypto
|
|
8
|
-
|
|
9
|
-
if (!webCrypto || typeof webCrypto.getRandomValues !== 'function') {
|
|
10
|
-
throw new Error(
|
|
11
|
-
'generate-password-lite: no Web Crypto implementation found. ' +
|
|
12
|
-
'A secure random source is required to generate passwords. ' +
|
|
13
|
-
'Use Node.js 18+, a modern browser, or polyfill `globalThis.crypto`.'
|
|
14
|
-
)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return webCrypto
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Returns a cryptographically secure integer in the range [0, upperLimit).
|
|
22
|
-
*
|
|
23
|
-
* Uses rejection sampling so that every value is equally likely. Taking a
|
|
24
|
-
* plain `random % upperLimit` would bias the low end of the range whenever
|
|
25
|
-
* `upperLimit` is not a power of two.
|
|
26
|
-
*/
|
|
27
|
-
export const generateRandomNumbers = (upperLimit: number): number => {
|
|
28
|
-
if (!Number.isInteger(upperLimit) || upperLimit <= 0) {
|
|
29
|
-
throw new RangeError(
|
|
30
|
-
`generate-password-lite: upperLimit must be a positive integer, received ${upperLimit}.`
|
|
31
|
-
)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const webCrypto = getWebCrypto()
|
|
35
|
-
const buffer = new Uint32Array(1)
|
|
36
|
-
|
|
37
|
-
// Largest multiple of upperLimit that fits in the Uint32 range. Draws at or
|
|
38
|
-
// above this cutoff are discarded rather than folded back into the range.
|
|
39
|
-
const cutoff = Math.floor(UINT32_RANGE / upperLimit) * upperLimit
|
|
40
|
-
|
|
41
|
-
let value: number
|
|
42
|
-
do {
|
|
43
|
-
webCrypto.getRandomValues(buffer)
|
|
44
|
-
value = buffer[0]!
|
|
45
|
-
} while (value >= cutoff)
|
|
46
|
-
|
|
47
|
-
return value % upperLimit
|
|
48
|
-
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import { generateRandomNumbers } from './generate-random-number'
|
|
2
|
-
import { shuffleString } from './shuffle-string'
|
|
3
|
-
import { ResolvedOptions } from '../types'
|
|
4
|
-
|
|
5
|
-
const LOWERCASE_CHARS = 'abcdefghijklmnopqrstuvwxyz'
|
|
6
|
-
const UPPERCASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
7
|
-
const NUMBER_CHARS = '0123456789'
|
|
8
|
-
const SYMBOL_CHARS = "!#$%&'()*+,-./:;<=>?@[]^_{|}~"
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Drops every excluded character. `String.replace` with a string pattern only
|
|
12
|
-
* removes the first match, so the exclusion is done with a set instead.
|
|
13
|
-
*/
|
|
14
|
-
const removeExceptions = (str: string, exclude: string): string => {
|
|
15
|
-
if (!exclude) return str
|
|
16
|
-
|
|
17
|
-
const banned = new Set([...exclude])
|
|
18
|
-
return [...str].filter(char => !banned.has(char)).join('')
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Picks `count` characters from `pool`. Throws when the caller asked for
|
|
23
|
-
* guaranteed characters out of a pool that `exclude` emptied.
|
|
24
|
-
*/
|
|
25
|
-
const pickFrom = (pool: string, count: number, name: string): string => {
|
|
26
|
-
if (count === 0) return ''
|
|
27
|
-
|
|
28
|
-
if (pool.length === 0) {
|
|
29
|
-
throw new Error(
|
|
30
|
-
`generate-password-lite: \`exclude\` removed every ${name} character, but \`minLength${name[0]!.toUpperCase()}${name.slice(1)}\` is ${count}.`
|
|
31
|
-
)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
let picked = ''
|
|
35
|
-
for (let i = 0; i < count; i++) {
|
|
36
|
-
picked += pool.charAt(generateRandomNumbers(pool.length))
|
|
37
|
-
}
|
|
38
|
-
return picked
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export const generatePswd = (options: ResolvedOptions): string => {
|
|
42
|
-
const {
|
|
43
|
-
length,
|
|
44
|
-
lowercase,
|
|
45
|
-
uppercase,
|
|
46
|
-
numbers,
|
|
47
|
-
symbols,
|
|
48
|
-
minLengthLowercase,
|
|
49
|
-
minLengthUppercase,
|
|
50
|
-
minLengthNumbers,
|
|
51
|
-
minLengthSymbols,
|
|
52
|
-
exclude,
|
|
53
|
-
} = options
|
|
54
|
-
|
|
55
|
-
const lowercaseChar = removeExceptions(LOWERCASE_CHARS, exclude)
|
|
56
|
-
const uppercaseChar = removeExceptions(UPPERCASE_CHARS, exclude)
|
|
57
|
-
const numberChar = removeExceptions(NUMBER_CHARS, exclude)
|
|
58
|
-
const symbolChar = removeExceptions(SYMBOL_CHARS, exclude)
|
|
59
|
-
|
|
60
|
-
// Characters that must appear, so that the password satisfies every
|
|
61
|
-
// `minLength*` the caller asked for.
|
|
62
|
-
const guaranteed =
|
|
63
|
-
pickFrom(lowercaseChar, minLengthLowercase, 'lowercase') +
|
|
64
|
-
pickFrom(uppercaseChar, minLengthUppercase, 'uppercase') +
|
|
65
|
-
pickFrom(numberChar, minLengthNumbers, 'numbers') +
|
|
66
|
-
pickFrom(symbolChar, minLengthSymbols, 'symbols')
|
|
67
|
-
|
|
68
|
-
// Every character the enabled classes still allow after exclusions.
|
|
69
|
-
const characterPool =
|
|
70
|
-
(lowercase ? lowercaseChar : '') +
|
|
71
|
-
(uppercase ? uppercaseChar : '') +
|
|
72
|
-
(numbers ? numberChar : '') +
|
|
73
|
-
(symbols ? symbolChar : '')
|
|
74
|
-
|
|
75
|
-
const remaining = length - guaranteed.length
|
|
76
|
-
|
|
77
|
-
if (remaining > 0 && characterPool.length === 0) {
|
|
78
|
-
throw new Error(
|
|
79
|
-
'generate-password-lite: `exclude` removed every character of every enabled class. No valid characters to generate the password from.'
|
|
80
|
-
)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
let filler = ''
|
|
84
|
-
for (let i = 0; i < remaining; i++) {
|
|
85
|
-
filler += characterPool.charAt(generateRandomNumbers(characterPool.length))
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Shuffle the whole password, not just the guaranteed part. Shuffling only
|
|
89
|
-
// the guaranteed characters would pin them to the leading positions and make
|
|
90
|
-
// the layout of the password predictable.
|
|
91
|
-
return shuffleString(guaranteed + filler)
|
|
92
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { GenerateOptions, ResolvedOptions } from '../types'
|
|
2
|
-
|
|
3
|
-
const withDefault = <T>(value: T | undefined, fallback: T): T =>
|
|
4
|
-
typeof value === 'undefined' ? fallback : value
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Fills in every unset option. Returns a new object so that the caller's
|
|
8
|
-
* options are never mutated.
|
|
9
|
-
*/
|
|
10
|
-
export const processOption = (options: GenerateOptions): ResolvedOptions => {
|
|
11
|
-
const lowercase = withDefault(options.lowercase, true)
|
|
12
|
-
const uppercase = withDefault(options.uppercase, true)
|
|
13
|
-
const numbers = withDefault(options.numbers, true)
|
|
14
|
-
const symbols = withDefault(options.symbols, false)
|
|
15
|
-
|
|
16
|
-
// A disabled character class can never contribute a minimum, regardless of
|
|
17
|
-
// what the caller passed in.
|
|
18
|
-
return {
|
|
19
|
-
length: withDefault(options.length, 10),
|
|
20
|
-
lowercase,
|
|
21
|
-
uppercase,
|
|
22
|
-
numbers,
|
|
23
|
-
symbols,
|
|
24
|
-
exclude: withDefault(options.exclude, ''),
|
|
25
|
-
minLengthLowercase: lowercase
|
|
26
|
-
? withDefault(options.minLengthLowercase, 1)
|
|
27
|
-
: 0,
|
|
28
|
-
minLengthUppercase: uppercase
|
|
29
|
-
? withDefault(options.minLengthUppercase, 1)
|
|
30
|
-
: 0,
|
|
31
|
-
minLengthNumbers: numbers ? withDefault(options.minLengthNumbers, 1) : 0,
|
|
32
|
-
minLengthSymbols: symbols ? withDefault(options.minLengthSymbols, 1) : 0,
|
|
33
|
-
}
|
|
34
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { generateRandomNumbers } from './generate-random-number'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Fisher-Yates shuffle backed by the same cryptographically secure source
|
|
5
|
-
* used to pick the characters themselves.
|
|
6
|
-
*
|
|
7
|
-
* Spreads across code points rather than UTF-16 units so that a surrogate
|
|
8
|
-
* pair supplied through `exclude` handling is never split in half.
|
|
9
|
-
*/
|
|
10
|
-
export const shuffleString = (str: string): string => {
|
|
11
|
-
const chars = [...str]
|
|
12
|
-
|
|
13
|
-
for (let i = chars.length - 1; i > 0; i--) {
|
|
14
|
-
const j = generateRandomNumbers(i + 1)
|
|
15
|
-
const tmp = chars[i]!
|
|
16
|
-
chars[i] = chars[j]!
|
|
17
|
-
chars[j] = tmp
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return chars.join('')
|
|
21
|
-
}
|
package/src/types.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
export interface GenerateOptions {
|
|
2
|
-
/**
|
|
3
|
-
* Length of the generated password.
|
|
4
|
-
* @default 10
|
|
5
|
-
*/
|
|
6
|
-
length?: number
|
|
7
|
-
/**
|
|
8
|
-
* Should the password include lowercase characters.
|
|
9
|
-
* @default true
|
|
10
|
-
*/
|
|
11
|
-
lowercase?: boolean
|
|
12
|
-
/**
|
|
13
|
-
* Should the password include uppercase characters.
|
|
14
|
-
* @default true
|
|
15
|
-
*/
|
|
16
|
-
uppercase?: boolean
|
|
17
|
-
/**
|
|
18
|
-
* Should the password include numbers.
|
|
19
|
-
* @default true
|
|
20
|
-
*/
|
|
21
|
-
numbers?: boolean
|
|
22
|
-
/**
|
|
23
|
-
* Should the password include symbol characters.
|
|
24
|
-
* @default false
|
|
25
|
-
*/
|
|
26
|
-
symbols?: boolean
|
|
27
|
-
/**
|
|
28
|
-
* Characters to exclude from the password.
|
|
29
|
-
* @default ""
|
|
30
|
-
*/
|
|
31
|
-
exclude?: string
|
|
32
|
-
/**
|
|
33
|
-
* Minimum number of lowercase characters. Forced to 0 when `lowercase` is false.
|
|
34
|
-
* @default 1 when `lowercase` is true, otherwise 0
|
|
35
|
-
*/
|
|
36
|
-
minLengthLowercase?: number
|
|
37
|
-
/**
|
|
38
|
-
* Minimum number of uppercase characters. Forced to 0 when `uppercase` is false.
|
|
39
|
-
* @default 1 when `uppercase` is true, otherwise 0
|
|
40
|
-
*/
|
|
41
|
-
minLengthUppercase?: number
|
|
42
|
-
/**
|
|
43
|
-
* Minimum number of numeric characters. Forced to 0 when `numbers` is false.
|
|
44
|
-
* @default 1 when `numbers` is true, otherwise 0
|
|
45
|
-
*/
|
|
46
|
-
minLengthNumbers?: number
|
|
47
|
-
/**
|
|
48
|
-
* Minimum number of symbol characters. Forced to 0 when `symbols` is false.
|
|
49
|
-
* @default 1 when `symbols` is true, otherwise 0
|
|
50
|
-
*/
|
|
51
|
-
minLengthSymbols?: number
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Every option resolved to a concrete value by `processOption`.
|
|
56
|
-
*/
|
|
57
|
-
export type ResolvedOptions = Required<GenerateOptions>
|