├── .editorconfig ├── .gitignore ├── 01_hash └── sha.ts ├── 02_mac └── hmac.ts ├── 03_kdf ├── argon2.ts ├── bcrypt.ts ├── pbkdf2.ts └── scrypt.ts ├── 04_prng └── prng.ts ├── 05_symmetric-encryption ├── aes-cbc-mimic-ecb.ts ├── aes-cbc.ts ├── aes-ecb.ts └── aes-gcm.ts ├── 06_key-exchange ├── dhke.ts └── ecdh.ts ├── 07_asymmetric-encryption ├── ecc.ts └── rsa.ts ├── 08_digital-signature ├── ecdsa.ts └── rsassa.ts ├── 09_jwt ├── jwe.ts ├── jwk.ts └── jws.ts ├── 10_otp ├── hotp.ts ├── qr-code.ts └── totp.ts ├── README.md ├── exam.md ├── package-lock.json ├── package.json └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 2 7 | indent_style = space 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules/ 3 | -------------------------------------------------------------------------------- /01_hash/sha.ts: -------------------------------------------------------------------------------- 1 | import { get } from 'fast-levenshtein'; 2 | import JsSHA from 'jssha'; 3 | import { v4 } from 'uuid'; 4 | 5 | const data: string = v4(); 6 | 7 | demo1(); 8 | demo2(); 9 | 10 | // 如何用依賴套件計算各種 SHA 值 11 | function demo1(): void { 12 | console.log(`Text : ${data}`); 13 | console.log(`SHA-1 : ${sha1(data)}`); 14 | console.log(`SHA2-256 : ${sha256(data)}`); 15 | console.log(`SHA2-512 : ${sha512(data)}`); 16 | console.log(`SHA3-256 : ${sha3_256(data)}`); 17 | console.log(`SHA3-512 : ${sha3_512(data)}`); 18 | } 19 | 20 | // 些微的輸入訊息變化,產生的 SHA 值會有很大的差異 21 | function demo2(): void { 22 | const modifiedData: string = `@${data.substring(1)}`; 23 | console.log(`Text : ${data}`); 24 | console.log(`SHA2-256 : ${sha256(data)}`); 25 | console.log(`Modified Text : ${modifiedData}`); 26 | console.log(`SHA2-256 : ${sha256(modifiedData)}`); 27 | console.log(`Distance of Text : ${get(data, modifiedData)}`); 28 | console.log(`Distance of Hash : ${get(sha256(data), sha256(modifiedData))}`); 29 | } 30 | 31 | function sha1(data: string): string { 32 | const shaObject = new JsSHA('SHA-1', 'TEXT'); 33 | shaObject.update(data); 34 | return shaObject.getHash('HEX'); 35 | } 36 | 37 | function sha256(data: string): string { 38 | const shaObject = new JsSHA('SHA-256', 'TEXT'); 39 | shaObject.update(data); 40 | return shaObject.getHash('HEX'); 41 | } 42 | 43 | function sha512(data: string): string { 44 | const shaObject = new JsSHA('SHA-512', 'TEXT'); 45 | shaObject.update(data); 46 | return shaObject.getHash('HEX'); 47 | } 48 | 49 | function sha3_256(data: string): string { 50 | const shaObject = new JsSHA('SHA3-256', 'TEXT'); 51 | shaObject.update(data); 52 | return shaObject.getHash('HEX'); 53 | } 54 | 55 | function sha3_512(data: string): string { 56 | const shaObject = new JsSHA('SHA3-512', 'TEXT'); 57 | shaObject.update(data); 58 | return shaObject.getHash('HEX'); 59 | } 60 | -------------------------------------------------------------------------------- /02_mac/hmac.ts: -------------------------------------------------------------------------------- 1 | import * as crypto from 'crypto'; 2 | import { v4 } from 'uuid'; 3 | 4 | const key: string = 'secret key'; 5 | const wrongKey: string = `@${key.substring(1)}`; 6 | const data: string = v4(); 7 | const wrongData: string = `@${data.substring(1)}`; 8 | const digest: string = hmacWithSha256(data, key); 9 | const wrongDigest: string = hmacWithSha256(data, wrongKey); 10 | 11 | console.log(`Key : ${key}`); 12 | console.log(`Text : ${data}`); 13 | console.log(`Wrong Key : ${wrongKey}`); 14 | console.log(`Wrong Text : ${wrongData}`); 15 | console.log(`HMAC Digest : ${digest}`); 16 | console.log(`Wrong HMAC Digest : ${wrongDigest}`); 17 | console.log(`Verify with correct text : ${verifyHmacWithSha256(data, digest, key)}`); 18 | console.log(`Verify with correct digest : ${verifyHmacWithSha256(data, digest, key)}`); 19 | console.log(`Verify with modified text : ${verifyHmacWithSha256(wrongData, digest, key)}`); 20 | console.log(`Verify with modified key : ${verifyHmacWithSha256(data, wrongDigest, key)}`); 21 | 22 | function hmacWithSha256(data: string, key: string): string { 23 | const hmac: crypto.Hmac = crypto.createHmac('sha256', key); 24 | hmac.update(data); 25 | return hmac.digest('hex'); 26 | } 27 | 28 | function verifyHmacWithSha256(data: string, digest: string, key: string): boolean { 29 | return digest === hmacWithSha256(data, key); 30 | } 31 | -------------------------------------------------------------------------------- /03_kdf/argon2.ts: -------------------------------------------------------------------------------- 1 | import * as argon2 from 'argon2'; 2 | import { v4 } from 'uuid'; 3 | 4 | const password: string = v4(); 5 | const wrongPassword: string = `@${password.substring(1)}`; 6 | let hash: string; 7 | let endTime: number; 8 | const startTime: number = new Date().getTime(); 9 | argon2id(password) 10 | .then(async (result: string) => { 11 | hash = result; 12 | endTime = new Date().getTime(); 13 | 14 | console.log(`Password : ${password}`); 15 | console.log(`Wrong Password : ${wrongPassword}`); 16 | console.log(`Hash : ${hash}`); 17 | console.log(`Verify with Correct Password : ${await verifyArgon2(hash, password)}`); 18 | console.log(`Verify with Wrong Password : ${await verifyArgon2(hash, wrongPassword)}`); 19 | console.log(`It costs ${endTime - startTime} ms`); 20 | }); 21 | 22 | async function argon2id(password: string): Promise { 23 | return argon2.hash(password, { type: argon2.argon2id }); 24 | } 25 | 26 | async function verifyArgon2(hash: string, password: string): Promise { 27 | return argon2.verify(hash, password); 28 | } 29 | -------------------------------------------------------------------------------- /03_kdf/bcrypt.ts: -------------------------------------------------------------------------------- 1 | import * as bcrypt from 'bcryptjs'; 2 | import { v4 } from 'uuid'; 3 | 4 | const password: string = v4(); 5 | const wrongPassword: string = `@${password.substring(1)}`; 6 | const rounds: number = 10; 7 | const salt: string = bcrypt.genSaltSync(rounds); 8 | const startTime: number = new Date().getTime(); 9 | const hash: string = bcryptSync(password, salt); 10 | const endTime: number = new Date().getTime(); 11 | 12 | console.log(`Password : ${password}`); 13 | console.log(`Wrong Password : ${wrongPassword}`); 14 | console.log(`Salt : ${salt}`); 15 | console.log(`Hash : ${bcryptSync(password, salt)}`); 16 | console.log(`Verify with Correct Password : ${verifyBcrypt(password, hash)}`); 17 | console.log(`Verify with Wrong Password : ${verifyBcrypt(wrongPassword, hash)}`); 18 | console.log(`It costs ${endTime - startTime} ms`); 19 | 20 | function bcryptSync(password: string, salt: string): string { 21 | return bcrypt.hashSync(password, salt); 22 | } 23 | 24 | function verifyBcrypt(password: string, hash: string): boolean { 25 | return bcrypt.compareSync(password, hash); 26 | } 27 | -------------------------------------------------------------------------------- /03_kdf/pbkdf2.ts: -------------------------------------------------------------------------------- 1 | import * as crypto from 'crypto'; 2 | import { v4 } from 'uuid'; 3 | 4 | const password: string = v4(); 5 | const wrongPassword: string = `@${password.substring(1)}`; 6 | const salt: string = crypto.randomBytes(16).toString('hex'); 7 | const iteration: number = 100000; 8 | 9 | const startTime: number = new Date().getTime(); 10 | const dK: string = pbkdf2Sync(password, salt, iteration); 11 | const endTime: number = new Date().getTime(); 12 | 13 | console.log(`Password : ${password}`); 14 | console.log(`Wrong Password : ${wrongPassword}`); 15 | console.log(`Salt : ${salt}`); 16 | console.log(`Derived Key : ${pbkdf2Sync(password, salt, iteration)}`); 17 | console.log(`Verify with Correct Password : ${verifyPbkdf2(password, salt, dK, iteration)}`); 18 | console.log(`Verify with Wrong Password : ${verifyPbkdf2(wrongPassword, salt, dK, iteration)}`); 19 | console.log(`It costs ${endTime - startTime} ms`); 20 | 21 | function pbkdf2Sync(password: string, salt: string, iteration: number = 100000, keyLength: number = 64, digest: string = 'sha256'): string { 22 | const key = crypto.pbkdf2Sync(password, salt, iteration, keyLength, digest); 23 | return key.toString('hex'); 24 | } 25 | 26 | function verifyPbkdf2(password: string, salt: string, dK: string, iteration: number): boolean { 27 | return dK === pbkdf2Sync(password, salt, iteration); 28 | } 29 | -------------------------------------------------------------------------------- /03_kdf/scrypt.ts: -------------------------------------------------------------------------------- 1 | import * as crypto from 'crypto'; 2 | import { v4 } from 'uuid'; 3 | 4 | const password: string = v4(); 5 | const wrongPassword: string = `@${password.substring(1)}`; 6 | const salt: string = crypto.randomBytes(16).toString('hex'); 7 | 8 | const startTime: number = new Date().getTime(); 9 | const dK: string = scryptSync(password, salt); 10 | const endTime: number = new Date().getTime(); 11 | 12 | console.log(`Password : ${password}`); 13 | console.log(`Wrong Password : ${wrongPassword}`); 14 | console.log(`Salt : ${salt}`); 15 | console.log(`Derived Key : ${scryptSync(password, salt)}`); 16 | console.log(`Verify with Correct Password : ${verifyScrypt(password, salt, dK)}`); 17 | console.log(`Verify with Wrong Password : ${verifyScrypt(wrongPassword, salt, dK)}`); 18 | console.log(`It costs ${endTime - startTime} ms`); 19 | 20 | function scryptSync(password: string, salt: string, keyLength: number = 64): string { 21 | const key = crypto.scryptSync(password, salt, keyLength); 22 | return key.toString('hex'); 23 | } 24 | 25 | function verifyScrypt(password: string, salt: string, dK: string): boolean { 26 | return dK === scryptSync(password, salt); 27 | } 28 | -------------------------------------------------------------------------------- /04_prng/prng.ts: -------------------------------------------------------------------------------- 1 | import MersenneTwister from 'mersenne-twister'; 2 | 3 | const fixSeed: number = 123456; 4 | 5 | const generator: MersenneTwister = new MersenneTwister(); 6 | generator.init_seed(fixSeed); 7 | 8 | const anotherGenerator: MersenneTwister = new MersenneTwister(); 9 | anotherGenerator.init_seed(fixSeed); 10 | 11 | console.log(`Seed: ${fixSeed}`); 12 | for (let i = 0; i < 10; i++) { 13 | console.log(`Generator A: ${i + 1} - ${generator.random()}`); 14 | console.log(`Generator B: ${i + 1} - ${anotherGenerator.random()}`); 15 | console.log(); 16 | } 17 | -------------------------------------------------------------------------------- /05_symmetric-encryption/aes-cbc-mimic-ecb.ts: -------------------------------------------------------------------------------- 1 | import * as aesjs from 'aes-js'; 2 | 3 | const key = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; 4 | const iv = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // Condition 1 5 | const text: string = '12345678901234561234567890123456'; 6 | 7 | console.log(aesCbcMimicEcbEncrypt(key, iv, text)); 8 | console.log(aesCbcMimicEcbDecrypt(key, iv, aesCbcMimicEcbEncrypt(key, iv, text)) === text); 9 | 10 | function aesCbcMimicEcbEncrypt(key: number[], iv: number[], text: string): string { 11 | const result: string[] = []; 12 | 13 | for (let i = 0; i < text.length; i += iv.length) { // Condition 2 14 | const subText: string = text.substring(i, i + iv.length); 15 | const textBytes: Uint8Array = aesjs.utils.utf8.toBytes(subText); 16 | const aesEcb: aesjs.ModeOfOperation.ModeOfOperationCBC = new aesjs.ModeOfOperation.cbc(key, iv); 17 | const encryptedBytes: Uint8Array = aesEcb.encrypt(textBytes); 18 | result.push(aesjs.utils.hex.fromBytes(encryptedBytes)); 19 | } 20 | 21 | return result.join(''); 22 | } 23 | 24 | function aesCbcMimicEcbDecrypt(key: number[], iv: number[], cipher: string): string { 25 | const result: string[] = []; 26 | 27 | for (let i = 0; i < cipher.length; i += iv.length * 2) { 28 | const subText: string = cipher.substring(i, i + iv.length * 2); 29 | const textBytes: Uint8Array = aesjs.utils.hex.toBytes(subText); 30 | const aesEcb: aesjs.ModeOfOperation.ModeOfOperationCBC = new aesjs.ModeOfOperation.cbc(key, iv); 31 | const decryptedBytes: Uint8Array = aesEcb.decrypt(textBytes); 32 | result.push(aesjs.utils.utf8.fromBytes(decryptedBytes)); 33 | } 34 | 35 | return result.join(''); 36 | } 37 | -------------------------------------------------------------------------------- /05_symmetric-encryption/aes-cbc.ts: -------------------------------------------------------------------------------- 1 | import * as aesjs from 'aes-js'; 2 | 3 | const key = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; 4 | const iv = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; 5 | const text: string = '123456789012345612345678901234561234567890123456'; 6 | 7 | console.log(`Text : ${text}`); 8 | console.log(`Cipher : ${aesCbcEncrypt(key, iv, text)}`); 9 | console.log(`Key : [${key.toString()}]`); 10 | console.log(`IV : [${iv.toString()}]`); 11 | console.log(aesCbcDecrypt(key, iv, aesCbcEncrypt(key, iv, text)) === text); 12 | 13 | function aesCbcEncrypt(key: number[], iv: number[], text: string): string { 14 | const textBytes: Uint8Array = aesjs.utils.utf8.toBytes(text); 15 | 16 | const aesEcb: aesjs.ModeOfOperation.ModeOfOperationCBC = new aesjs.ModeOfOperation.cbc(key, iv); 17 | const encryptedBytes: Uint8Array = aesEcb.encrypt(textBytes); 18 | 19 | return aesjs.utils.hex.fromBytes(encryptedBytes); 20 | } 21 | 22 | function aesCbcDecrypt(key: number[], iv: number[], cipher: string): string { 23 | const textBytes: Uint8Array = aesjs.utils.hex.toBytes(cipher); 24 | 25 | const aesEcb: aesjs.ModeOfOperation.ModeOfOperationCBC = new aesjs.ModeOfOperation.cbc(key, iv); 26 | const decryptedBytes: Uint8Array = aesEcb.decrypt(textBytes); 27 | 28 | return aesjs.utils.utf8.fromBytes(decryptedBytes); 29 | } 30 | -------------------------------------------------------------------------------- /05_symmetric-encryption/aes-ecb.ts: -------------------------------------------------------------------------------- 1 | import * as aesjs from 'aes-js'; 2 | 3 | const key = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; 4 | const text: string = '123456789012345600000000000000001234567890123456'; 5 | console.log(`Text : ${text}`); 6 | console.log(`Cipher : ${aesEcbEncrypt(key, text)}`); 7 | console.log(`Key : [${key.toString()}]`); 8 | console.log(aesEcbDecrypt(key, aesEcbEncrypt(key, text)) === text); 9 | 10 | // 如何讓以下的程式印出 true? 11 | // console.log(aesEcbDecrypt(key, '') === '123456789012345612345678901234561234567890123456') 12 | 13 | function aesEcbEncrypt(key: number[], text: string): string { 14 | const textBytes: Uint8Array = aesjs.utils.utf8.toBytes(text); 15 | 16 | const aesEcb: aesjs.ModeOfOperation.ModeOfOperationECB = new aesjs.ModeOfOperation.ecb(key); 17 | const encryptedBytes: Uint8Array = aesEcb.encrypt(textBytes); 18 | 19 | return aesjs.utils.hex.fromBytes(encryptedBytes); 20 | } 21 | 22 | function aesEcbDecrypt(key: number[], cipher: string): string { 23 | const textBytes: Uint8Array = aesjs.utils.hex.toBytes(cipher); 24 | 25 | const aesEcb: aesjs.ModeOfOperation.ModeOfOperationECB = new aesjs.ModeOfOperation.ecb(key); 26 | const decryptedBytes: Uint8Array = aesEcb.decrypt(textBytes); 27 | 28 | return aesjs.utils.utf8.fromBytes(decryptedBytes); 29 | } 30 | -------------------------------------------------------------------------------- /05_symmetric-encryption/aes-gcm.ts: -------------------------------------------------------------------------------- 1 | // ref: https://gist.github.com/rjz/15baffeab434b8125ca4d783f4116d81 2 | 3 | import { 4 | BinaryLike, 5 | CipherGCM, 6 | CipherGCMTypes, 7 | CipherKey, 8 | createCipheriv, 9 | createDecipheriv, 10 | randomBytes 11 | } from 'crypto'; 12 | 13 | const key = new Uint8Array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]); 14 | const text: string = '12345678901234561234567890123456'; 15 | const algorithm: CipherGCMTypes = 'aes-128-gcm'; 16 | 17 | const [cipher, iv, tag]: [string, Uint8Array, Buffer] = aesGcmEncrypt(key, text); 18 | const decrypted: string = aesGcmDecrypt(key, iv, tag, cipher); 19 | console.log(`Text : ${text}`); 20 | console.log(`Cipher : ${cipher}`); 21 | console.log(`Key : [${key.toString()}]`); 22 | console.log(`IV : [${iv.toString()}]`); 23 | console.log(`Tag : ${tag.toString('hex')}`) 24 | console.log(decrypted === text); 25 | 26 | function aesGcmEncrypt(key: CipherKey, text: string): [string, Uint8Array, Buffer] { 27 | const iv: Uint8Array = new Uint8Array(randomBytes(128 / 8)) 28 | const aesGcm: CipherGCM = createCipheriv(algorithm, key, iv); 29 | 30 | let cipher: string = aesGcm.update(text, 'utf8', 'hex'); 31 | cipher += aesGcm.final('hex'); 32 | 33 | return [cipher, iv, aesGcm.getAuthTag()]; 34 | } 35 | 36 | 37 | function aesGcmDecrypt(key: BinaryLike, iv: Uint8Array, tag: Buffer, cipher: string): string { 38 | const decipher = createDecipheriv(algorithm, key, iv); 39 | decipher.setAuthTag(tag); 40 | 41 | let text: string = decipher.update(cipher, 'hex', 'utf8'); 42 | text += decipher.final('utf8'); 43 | 44 | return text; 45 | } 46 | -------------------------------------------------------------------------------- /06_key-exchange/dhke.ts: -------------------------------------------------------------------------------- 1 | import * as crypto from 'crypto'; 2 | import * as assert from 'assert'; 3 | 4 | const alice: crypto.DiffieHellman = crypto.createDiffieHellman(8); 5 | const primeFromAlice: string = alice.getPrime('hex'); 6 | const generatorFromAlice: string = alice.getGenerator('hex'); 7 | const keyFromAlice = alice.generateKeys('hex'); 8 | console.log('Key Exchange Agreements for Alice:'); 9 | logDetails(alice); 10 | 11 | const bob = crypto.createDiffieHellman(primeFromAlice, 'hex', generatorFromAlice, 'hex'); 12 | const keyFromBob = bob.generateKeys('hex'); 13 | console.log('Key Exchange Agreements for Bob:'); 14 | logDetails(bob); 15 | 16 | const secret1 = alice.computeSecret(keyFromBob, 'hex', 'hex'); 17 | const secret2 = bob.computeSecret(keyFromAlice, 'hex', 'hex'); 18 | assert.strictEqual(secret1, secret2); 19 | console.log(`Shared Secret: ${parseInt(secret1, 16)}`); 20 | 21 | // http://www.irongeek.com/diffie-hellman.php 22 | function logDetails(dh: crypto.DiffieHellman): void { 23 | let keyExchangeArguments: any = { 24 | primeNumber: null, // which is p 25 | primitiveRoot: null, // which is g 26 | privateX: null, // the only secret parameter for each of its participant 27 | publicY: null, // the public key which each of participant exchange with other part 28 | }; 29 | 30 | keyExchangeArguments.primeNumber = dh.getPrime().toString('hex') 31 | keyExchangeArguments.primitiveRoot = dh.getGenerator().toString('hex') 32 | keyExchangeArguments.privateX = dh.getPrivateKey().toString('hex') 33 | keyExchangeArguments.publicY = dh.getPublicKey().toString('hex') 34 | 35 | console.log(` - Prime Number : ${parseInt(keyExchangeArguments.primeNumber, 16)}`); 36 | console.log(` - Primitive Root : ${parseInt(keyExchangeArguments.primitiveRoot, 16)}`); 37 | console.log(` - Private X : ${parseInt(keyExchangeArguments.privateX, 16)}`); 38 | console.log(` - Public Y : ${parseInt(keyExchangeArguments.publicY, 16)}`); 39 | console.log(); 40 | } 41 | -------------------------------------------------------------------------------- /06_key-exchange/ecdh.ts: -------------------------------------------------------------------------------- 1 | import * as crypto from 'crypto'; 2 | import * as assert from 'assert'; 3 | 4 | const curveName: string = 'secp256k1'; 5 | 6 | const alice: crypto.ECDH = crypto.createECDH(curveName); 7 | alice.generateKeys(); 8 | console.log('Key Exchange Agreements for Alice:'); 9 | logDetails(alice); 10 | 11 | const bob = crypto.createECDH(curveName); 12 | bob.generateKeys(); 13 | console.log('Key Exchange Agreements for Bob:'); 14 | logDetails(bob); 15 | 16 | const secret1 = alice.computeSecret(bob.getPublicKey().toString('hex'), 'hex', 'hex'); 17 | const secret2 = bob.computeSecret(alice.getPublicKey().toString('hex'), 'hex', 'hex'); 18 | assert.strictEqual(secret1, secret2); 19 | console.log(`Secret: ${secret1}`); 20 | 21 | function logDetails(dh: crypto.ECDH): void { 22 | let keyExchangeArguments: any = { 23 | publicKey: null, 24 | privateKey: null, 25 | }; 26 | 27 | keyExchangeArguments.privateKey = dh.getPrivateKey().toString('hex') 28 | keyExchangeArguments.publicKey = dh.getPublicKey().toString('hex') 29 | 30 | console.log(` - Private Key : ${keyExchangeArguments.privateKey}`); 31 | console.log(` - Public Key : ${keyExchangeArguments.publicKey}`); 32 | console.log(); 33 | } 34 | -------------------------------------------------------------------------------- /07_asymmetric-encryption/ecc.ts: -------------------------------------------------------------------------------- 1 | import eccrypto, { Ecies } from 'eccrypto'; 2 | import { v4 } from 'uuid'; 3 | 4 | const privateKeyA = eccrypto.generatePrivate(); 5 | const publicKeyA = eccrypto.getPublic(privateKeyA); 6 | const privateKeyB = eccrypto.generatePrivate(); 7 | const publicKeyB = eccrypto.getPublic(privateKeyB); 8 | const data: string = v4(); 9 | 10 | encryptMsgForA(data).then(() => { 11 | console.log(); 12 | encryptMsgForB(data).then(() => { 13 | }); 14 | }); 15 | 16 | async function encrypt(publicKey: Buffer, text: string): Promise { 17 | return await eccrypto.encrypt(publicKey, Buffer.from(text)); 18 | } 19 | 20 | async function decrypt(privateKey: Buffer, cipher: Ecies): Promise { 21 | return await eccrypto.decrypt(privateKey, cipher); 22 | } 23 | 24 | // Encrypting the message for A. 25 | async function encryptMsgForA(data: string): Promise { 26 | const cipher: Ecies = await encrypt(publicKeyA, data); 27 | const text: Buffer = await decrypt(privateKeyA, cipher); 28 | console.log(`Message to party A : ${text.toString()}`); 29 | console.log(`Cipher : ${cipher.ciphertext.toString('hex')}`); 30 | console.log(`Public Key : ${cipher.ephemPublicKey.toString('hex')}`); 31 | console.log(`IV : ${cipher.iv.toString('hex')}`); 32 | console.log(`MAC : ${cipher.mac.toString('hex')}`); 33 | } 34 | 35 | // Encrypting the message for B. 36 | async function encryptMsgForB(data: string): Promise { 37 | const cipher: Ecies = await encrypt(publicKeyB, data); 38 | const text: Buffer = await decrypt(privateKeyB, cipher); 39 | console.log(`Message to party B : ${text.toString()}`); 40 | console.log(`Cipher : ${cipher.ciphertext.toString('hex')}`); 41 | console.log(`Public Key : ${cipher.ephemPublicKey.toString('hex')}`); 42 | console.log(`IV : ${cipher.iv.toString('hex')}`); 43 | console.log(`MAC : ${cipher.mac.toString('hex')}`); 44 | } 45 | -------------------------------------------------------------------------------- /07_asymmetric-encryption/rsa.ts: -------------------------------------------------------------------------------- 1 | import { pki, util } from 'node-forge'; 2 | import { v4 } from 'uuid'; 3 | 4 | const bits: number = 2048; 5 | const keyPair: pki.rsa.KeyPair = pki.rsa.generateKeyPair({ bits: bits }); 6 | const randomKeyPair: pki.rsa.KeyPair = pki.rsa.generateKeyPair({ bits: bits }); 7 | const data: string = v4(); 8 | const longData: string = data.repeat(5) + '0000000000000000000000000000000000'; 9 | console.log(`PCKS#8:`); 10 | console.log(`${keyToPem(keyPair)}`); 11 | 12 | console.log(`Text : ${data}`) 13 | console.log(`Encrypt Text : ${rsaOaepEncrypt(keyPair.publicKey, data)}`); 14 | console.log(`Decrypt Text : ${rsaOaepDecrypt(keyPair.privateKey, rsaOaepEncrypt(keyPair.publicKey, data))}`); 15 | //console.log(`Decrypt using wrong key : ${rsaOaepDecrypt(randomKeyPair.privateKey, rsaOaepEncrypt(keyPair.publicKey, data))}`) 16 | 17 | console.log(); 18 | 19 | console.log(`(${bits}/8) – 42 = ${bits/8} – 42 = ${bits/8-42}`); 20 | console.log(`Long Text (${longData.length}) : ${longData}`); 21 | console.log(`Encrypt Long Text : ${rsaOaepEncrypt(keyPair.publicKey, longData)}`); 22 | 23 | function keyToPem(keyPair: pki.rsa.KeyPair): pki.PEM { 24 | const ans1PrivateKey: any = pki.privateKeyToAsn1(keyPair.privateKey); 25 | const ans1PrivateKeyInfo: any = pki.wrapRsaPrivateKey(ans1PrivateKey); 26 | return pki.privateKeyInfoToPem(ans1PrivateKeyInfo); 27 | } 28 | 29 | function rsaOaepEncrypt(publicKey: pki.rsa.PublicKey, text: string): string { 30 | return util.bytesToHex(publicKey.encrypt(text, 'RSA-OAEP')); 31 | } 32 | 33 | function rsaOaepDecrypt(privateKey: pki.rsa.PrivateKey, cipher: string): string { 34 | return privateKey.decrypt(util.hexToBytes(cipher), 'RSA-OAEP'); 35 | } 36 | -------------------------------------------------------------------------------- /08_digital-signature/ecdsa.ts: -------------------------------------------------------------------------------- 1 | import * as crypto from 'crypto'; 2 | import eccrypto from 'eccrypto'; 3 | import { v4 } from 'uuid'; 4 | 5 | const privateKey = eccrypto.generatePrivate(); 6 | const publicKey = eccrypto.getPublic(privateKey); 7 | 8 | const data = v4(); 9 | const digest: Buffer = crypto.createHash("sha256").update(data).digest(); 10 | 11 | eccrypto.sign(privateKey, digest) 12 | .then(async (signature: Buffer) => { 13 | console.log(`Text : ${data}`); 14 | console.log(`Digest : ${digest.toString('hex')}`) 15 | try { 16 | console.log(`Signature : ${signature.toString('hex')}`); 17 | // @ts-ignore 18 | await eccrypto.verify(publicKey, digest, signature); 19 | console.log("Signature is OK") 20 | } catch (error) { 21 | console.log("Signature is BAD") 22 | } 23 | 24 | try { 25 | const modifiedSignature: Buffer = signature.reverse(); 26 | console.log(`Modified Signature : ${modifiedSignature.toString('hex')}`); 27 | // @ts-ignore 28 | await eccrypto.verify(publicKey, digest, modifiedSignature); 29 | console.log("Signature is OK") 30 | } catch (error) { 31 | console.log("Signature is BAD") 32 | } 33 | }); 34 | -------------------------------------------------------------------------------- /08_digital-signature/rsassa.ts: -------------------------------------------------------------------------------- 1 | import * as forge from 'node-forge'; 2 | import { v4 } from 'uuid'; 3 | 4 | const bits: number = 2048; 5 | const keyPair: forge.pki.rsa.KeyPair = forge.pki.rsa.generateKeyPair({ bits: bits }); 6 | const data: string = v4(); 7 | const md: forge.md.MessageDigest = forge.md.sha1.create().update(data, 'utf8'); 8 | const digest: forge.Bytes = md.digest().bytes(); 9 | 10 | // sign data with a private key and output DigestInfo DER-encoded bytes 11 | // (defaults to RSASSA PKCS#1 v1.5) 12 | const signature: forge.Bytes = keyPair.privateKey.sign(md); 13 | console.log(`Signature : ${forge.util.bytesToHex(signature)}`); 14 | 15 | // verify data with a public key 16 | // (defaults to RSASSA PKCS#1 v1.5) 17 | try { 18 | const verified: boolean = keyPair.publicKey.verify(digest, signature); 19 | console.log(`Verify Result : ${verified}`); 20 | } catch (error) { 21 | console.error(error); 22 | } 23 | 24 | console.log(); 25 | 26 | const modifiedSignature: string = `@${signature.substring(1)}`; 27 | console.log(`Modified Signature : ${forge.util.bytesToHex(modifiedSignature)}`); 28 | try { 29 | const verified: boolean = keyPair.publicKey.verify(digest, modifiedSignature); 30 | console.log(`Verify Result : ${verified}`); 31 | } catch (error) { 32 | console.error(error); 33 | } 34 | -------------------------------------------------------------------------------- /09_jwt/jwe.ts: -------------------------------------------------------------------------------- 1 | import dayjs from 'dayjs'; 2 | import { JWK, JWE } from 'jose'; 3 | import { v4 } from 'uuid'; 4 | 5 | const privateKey: JWK.RSAKey = JWK.generateSync('RSA', 2048, { 'alg': 'RSA-OAEP', use: 'enc', kid: v4()}); 6 | const publicKey: JWK.RSAKey = JWK.asKey(privateKey.toJWK()); 7 | const anotherPrivateKey: JWK.RSAKey = JWK.generateSync('RSA', 2048, { 'alg': 'RSA-OAEP', use: 'enc', kid: v4()}); 8 | const payload: object = { 9 | iss: 'issuer', 10 | aud: 'audience', 11 | testKey: 'testValue', 12 | iat: dayjs().unix(), 13 | exp: dayjs().add(5, 'minute').unix(), 14 | }; 15 | const jwe: string = encrypt(JSON.stringify(payload), publicKey); 16 | 17 | console.log(`JWE : ${jwe}`); 18 | console.log(`Decrypt with correct key : ${decrypt(jwe, privateKey)}`); 19 | console.log(`Decrypt with wrong key : ${decrypt(jwe, anotherPrivateKey)}`); 20 | console.log(`Decrypt with wrong jwe : ${decrypt(jwe.substring(1), privateKey)}`); 21 | 22 | function encrypt(payload: string, key: JWK.Key): string { 23 | return JWE.encrypt(payload, key, { 'typ': 'JWT', 'kid': key.kid }); 24 | } 25 | 26 | function decrypt(jwe: string, key: JWK.Key): string { 27 | try { 28 | return JWE.decrypt(jwe, key).toString('utf8'); 29 | } catch (error) { 30 | return ''; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /09_jwt/jwk.ts: -------------------------------------------------------------------------------- 1 | import { JWK } from 'jose'; 2 | import { v4 } from 'uuid'; 3 | 4 | generateRsaKey(); 5 | generateEccKey(); 6 | 7 | function generateRsaKey(): void { 8 | const rsaKey: JWK.RSAKey = JWK.generateSync('RSA', 2048, { alg: 'RS256', use: 'sig', kid: v4()}); 9 | console.log('Private Key:'); 10 | console.log(rsaKey.toJWK(true)); 11 | console.log('Public Key:'); 12 | console.log(rsaKey.toJWK()); 13 | } 14 | 15 | function generateEccKey(): void { 16 | const eccKey: JWK.ECKey = JWK.generateSync('EC', 'P-256', { alg: 'ES256', use: 'sig', kid: v4()}); 17 | console.log('Private Key:'); 18 | console.log(eccKey.toJWK(true)); 19 | console.log('Public Key:'); 20 | console.log(eccKey.toJWK()); 21 | } 22 | -------------------------------------------------------------------------------- /09_jwt/jws.ts: -------------------------------------------------------------------------------- 1 | import dayjs from 'dayjs'; 2 | import { JWK, JWS } from 'jose'; 3 | import { v4 } from 'uuid'; 4 | 5 | const privateKey: JWK.ECKey = JWK.generateSync('EC', 'P-256', { alg: 'ES256', use: 'sig', kid: v4()}); 6 | const publicKey: JWK.ECKey = JWK.asKey(privateKey.toJWK()); 7 | const anotherPublicKey: JWK.ECKey = JWK.generateSync('EC', 'P-256', { alg: 'ES256', use: 'sig', kid: v4()}, false); 8 | const payload: object = { 9 | iss: 'issuer', 10 | aud: 'audience', 11 | testKey: 'testValue', 12 | iat: dayjs().unix(), 13 | exp: dayjs().add(5, 'minute').unix(), 14 | }; 15 | const jws: string = sign(payload, privateKey); 16 | 17 | console.log(`JWS : ${jws}`); 18 | console.log(`Verify with correct key : ${verify(jws, publicKey)}`); 19 | console.log(`Verify with wrong key : ${verify(jws, anotherPublicKey)}`); 20 | console.log(`Verify with wrong jws : ${verify(jws.substring(1), publicKey)}`); 21 | 22 | function sign(payload: object, key: JWK.Key): string { 23 | return JWS.sign(payload, key, { 'typ': 'JWT', 'kid': key.kid }); 24 | } 25 | 26 | function verify(jws: string, key: JWK.Key): boolean { 27 | try { 28 | JWS.verify(jws, key); 29 | return true; 30 | } catch (error) { 31 | return false; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /10_otp/hotp.ts: -------------------------------------------------------------------------------- 1 | import { hotp } from 'otplib'; 2 | 3 | const secret = 'KVKFKRCPNZQUYMLXOVYDSQKJKZDTSRLD'; 4 | const counter = 1; // it should be a random number 5 | 6 | const token = generateToken(secret, counter); 7 | console.log(token); 8 | console.log(checkToken(token, secret, counter)); 9 | 10 | console.log(`Current counter is ${counter}`); 11 | console.log(`Add counter to ${counter + 1}`); 12 | console.log(checkToken(token, secret, counter + 1)); 13 | 14 | function generateToken(secret: string, counter: number): string { 15 | return hotp.generate(secret, counter); 16 | } 17 | 18 | function checkToken(token: string, secret: string, counter: number): boolean { 19 | try { 20 | return hotp.check(token, secret, counter); 21 | } catch (err) { 22 | console.error(err); 23 | return false; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /10_otp/qr-code.ts: -------------------------------------------------------------------------------- 1 | import { authenticator } from '@otplib/preset-default'; 2 | import qrcode from 'qrcode'; 3 | 4 | const user = 'your-gmail-account@gmail.com'; 5 | const service = 'Google'; 6 | const secret = authenticator.generateSecret(); 7 | const otpauth = authenticator.keyuri(user, service, secret); 8 | 9 | generateQrCode().then((result: string) => { 10 | console.log(result); 11 | }) 12 | 13 | async function generateQrCode(): Promise { 14 | return await qrcode.toDataURL(otpauth); 15 | } 16 | -------------------------------------------------------------------------------- /10_otp/totp.ts: -------------------------------------------------------------------------------- 1 | import { authenticator } from '@otplib/preset-default'; 2 | 3 | const secret = authenticator.generateSecret(); 4 | // console.log(authenticator.allOptions()); 5 | 6 | const token = generateToken(secret); 7 | console.log(token); 8 | console.log(checkToken(token, secret)); 9 | 10 | console.log('Wait 30 secs'); 11 | setTimeout(() => { 12 | console.log(checkToken(token, secret)); 13 | }, 30000); 14 | 15 | function generateToken(secret: string): string { 16 | return authenticator.generate(secret); 17 | } 18 | 19 | function checkToken(token: string, secret: string): boolean { 20 | try { 21 | return authenticator.check(token, secret); 22 | } catch (err) { 23 | console.error(err); 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 建議開發者知道的密碼學知識 2 | 3 | ## 第一次課程 4 | 5 | ### Hash 6 | - Hash 是做什麼用的? 7 | - Hash 的特性 8 | - 什麼是 Cryptographic Hash Function? 9 | - 常見演算法 10 | - 迷思:雜湊不等於加密 11 | 12 | ### Message Authentication Code 13 | - 如何確認訊息未被竄改? 14 | - 常見演算法 15 | 16 | ### Key Derivation Function 17 | - KDF 是什麼? 18 | - 密碼要怎麼存放? 19 | - 常見演算法 20 | 21 | ### Random Number Generator 22 | - 什麼是隨機亂數? 23 | - 什麼是 CSPRNG? 24 | 25 | ### Symmetric Encryption 26 | - 訊息的機密性、完整性、不可否認性是什麼意思? 27 | - 對稱式跟非對稱式是怎麼區分的? 28 | - XOR 運算是什麼? 29 | - AES 是什麼? 30 | - AES Mode of Operation 又是什麼? 31 | - 迷思:AES 一定是安全的嗎? 32 | - 如何確保訊息完整性? 33 | - 迷思:雜湊不等於加密 34 | 35 | --- 36 | 37 | ## 第二次課程 38 | 39 | ### Key Exchange 40 | - 金鑰交換的目的 41 | - Key Exchange 作法 42 | 43 | ### Asymmetric Encryption 44 | - 用同一把 Key 做事情會有什麼問題? 45 | - 非對稱式是什麼意思? 46 | - 常見演算法族系 47 | - 為什麼不能夠使用 Asymmetric Encryption 來加密任何東西?如何用 Hybrid Cryptography System 來克服? 48 | 49 | ### Digital Signature 50 | - 訊息的不可否認性怎麼做到的? 51 | - 簽章與查驗 52 | - 數位簽章可以做什麼用? 53 | 54 | --- 55 | 56 | ## 第三次課程 57 | 58 | ### SSL/TLS 59 | - TLS 可以做到怎樣的保護? 60 | - TLS Handshake 61 | - TLS Cipher Suites 62 | - 數位憑證是怎麼運作的? 63 | 64 | ### JSON Web Token 65 | - JWT 是什麼? 66 | - JWT 有那些變形? 67 | - JWT 常見用途 68 | 69 | ### 其他應用 70 | - One Time Password 是什麼? 71 | 72 | --- 73 | 74 | ## 課後評量 75 | 76 | - [評量考券](exam.md) 77 | -------------------------------------------------------------------------------- /exam.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: cryptography 3 | --- 4 | 5 | # 密碼學考題試券 6 | 7 | ## 考試規則 8 | 9 | - 全部 30 題是非題,正確比率超過或包含 70% 即算通過。 10 | - 作答時間不限制,可重播影片來協助答題。 11 | - 若對試題有疑問,可至 https://github.com/yaosiang/cryptography-course 發 issue 詢問。 12 | 13 | ### Hash 14 | 15 | - Q:密碼雜湊函式可以使用已經被證明會產生碰撞的雜湊函式。 16 | - Q:不管訊息長度大小,在經過密碼雜湊函式處理過產出的 Hash 值,長度會是固定的。 17 | - Q:密碼雜湊函式極難從 Hash 值反推回原始訊息。 18 | 19 | ### MAC 20 | 21 | - Q:MAC 可以在 pre-shared secret 的情況下,確保訊息完整性跟訊息來源。 22 | - Q:MAC 可以提供訊息的保密。 23 | 24 | ### KDF 25 | 26 | - Q:密碼可以明文或加密形式存放沒關係。 27 | - Q:Salted hased password 的安全強度比 Secure KDF 高。 28 | - Q:常見 KDF 演算法的運算速度跟密碼雜湊函式一樣快速。 29 | 30 | ### Symmetric Encrytion 31 | 32 | - Q:對稱式演算法的對稱,是相同明文在加密後都會產生一樣密文的意思。 33 | - Q:工作模式(mode of operation)是在講區塊加密演算法(如:AES)如何處理多個區塊訊息的方式。 34 | - Q:在沒有金鑰(key)的情況下,使用 AES-ECB 無法透過修改密文來操縱解開的明文。 35 | - Q:使用 AES-GCM 沒有辦法確保訊息完整性。 36 | 37 | ### Key Exchange 38 | 39 | - Q:透過 Key Exchange,可以在不安全的管道上,雙方協調出一個 shared secret。 40 | - Q:單純的 Diffie–Hellman Key Exchange 有可能受到中間人攻擊。 41 | 42 | ### Asymmteric Encryption 43 | 44 | - Q:公鑰跟私鑰在數學上有一定關係。 45 | - Q:公鑰也應該如同私鑰一般的保管及存放。 46 | - Q:RSA 與 ECC 是兩種常見的非對稱式加密演算法。 47 | - Q:RSA 的金鑰長度比 ECC 來的長。 48 | - Q:單純的非對稱式加密可以加密任意長度的訊息。 49 | - Q:非對稱式加密是使用公鑰來加密。 50 | 51 | ### Digital Signatures 52 | 53 | - Q:使用數位簽章可以確保訊息的不可否認性。 54 | - Q:數位簽章是使用公鑰對訊息雜湊值做簽署(sign)。 55 | - Q:收到數位簽章跟原始訊息的接收者,需要使用公鑰來查驗(verify)數位簽章是否正確。 56 | 57 | ### TLS/SSL 58 | 59 | - Q:目前(2020 年 6 月)最新的 TLS 版本是 1.3。 60 | - Q:Certificate Authority 會透過簽發數位憑證(certificate)來確保公鑰的合法性。 61 | - Q:Root CA 的數位憑證(或稱根憑證)會透過瀏覽器軟體來散佈。 62 | - Q:數位憑證的信任鍊若斷掉,則 TLS Handshake 仍然可以建立。 63 | - Q:TLS 在 Handshake 階段完成後會協調出一把 session key,這把 key 會在後續用對稱式加密演算法來加密傳遞的資訊。 64 | 65 | ### JWT 66 | 67 | - Q:JWT 是種 Token 傳遞格式,只有訊息簽章的 Token 稱為 JWS(JSON Web Signature),若要加密訊息,則需要使用 JWE(JSON Web Encryption)。 68 | - Q:使用 JWT 可以不查驗簽章,也可以把表頭的 alg 設定成 none。 69 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cryptography-course", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@nodelib/fs.scandir": { 8 | "version": "2.1.3", 9 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", 10 | "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", 11 | "dev": true, 12 | "requires": { 13 | "@nodelib/fs.stat": "2.0.3", 14 | "run-parallel": "^1.1.9" 15 | } 16 | }, 17 | "@nodelib/fs.stat": { 18 | "version": "2.0.3", 19 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", 20 | "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", 21 | "dev": true 22 | }, 23 | "@nodelib/fs.walk": { 24 | "version": "1.2.4", 25 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", 26 | "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", 27 | "dev": true, 28 | "requires": { 29 | "@nodelib/fs.scandir": "2.1.3", 30 | "fastq": "^1.6.0" 31 | } 32 | }, 33 | "@otplib/core": { 34 | "version": "12.0.1", 35 | "resolved": "https://registry.npmjs.org/@otplib/core/-/core-12.0.1.tgz", 36 | "integrity": "sha512-4sGntwbA/AC+SbPhbsziRiD+jNDdIzsZ3JUyfZwjtKyc/wufl1pnSIaG4Uqx8ymPagujub0o92kgBnB89cuAMA==" 37 | }, 38 | "@otplib/plugin-crypto": { 39 | "version": "12.0.1", 40 | "resolved": "https://registry.npmjs.org/@otplib/plugin-crypto/-/plugin-crypto-12.0.1.tgz", 41 | "integrity": "sha512-qPuhN3QrT7ZZLcLCyKOSNhuijUi9G5guMRVrxq63r9YNOxxQjPm59gVxLM+7xGnHnM6cimY57tuKsjK7y9LM1g==", 42 | "requires": { 43 | "@otplib/core": "^12.0.1" 44 | } 45 | }, 46 | "@otplib/plugin-thirty-two": { 47 | "version": "12.0.1", 48 | "resolved": "https://registry.npmjs.org/@otplib/plugin-thirty-two/-/plugin-thirty-two-12.0.1.tgz", 49 | "integrity": "sha512-MtT+uqRso909UkbrrYpJ6XFjj9D+x2Py7KjTO9JDPhL0bJUYVu5kFP4TFZW4NFAywrAtFRxOVY261u0qwb93gA==", 50 | "requires": { 51 | "@otplib/core": "^12.0.1", 52 | "thirty-two": "^1.0.2" 53 | } 54 | }, 55 | "@otplib/preset-default": { 56 | "version": "12.0.1", 57 | "resolved": "https://registry.npmjs.org/@otplib/preset-default/-/preset-default-12.0.1.tgz", 58 | "integrity": "sha512-xf1v9oOJRyXfluBhMdpOkr+bsE+Irt+0D5uHtvg6x1eosfmHCsCC6ej/m7FXiWqdo0+ZUI6xSKDhJwc8yfiOPQ==", 59 | "requires": { 60 | "@otplib/core": "^12.0.1", 61 | "@otplib/plugin-crypto": "^12.0.1", 62 | "@otplib/plugin-thirty-two": "^12.0.1" 63 | } 64 | }, 65 | "@otplib/preset-v11": { 66 | "version": "12.0.1", 67 | "resolved": "https://registry.npmjs.org/@otplib/preset-v11/-/preset-v11-12.0.1.tgz", 68 | "integrity": "sha512-9hSetMI7ECqbFiKICrNa4w70deTUfArtwXykPUvSHWOdzOlfa9ajglu7mNCntlvxycTiOAXkQGwjQCzzDEMRMg==", 69 | "requires": { 70 | "@otplib/core": "^12.0.1", 71 | "@otplib/plugin-crypto": "^12.0.1", 72 | "@otplib/plugin-thirty-two": "^12.0.1" 73 | } 74 | }, 75 | "@panva/asn1.js": { 76 | "version": "1.0.0", 77 | "resolved": "https://registry.npmjs.org/@panva/asn1.js/-/asn1.js-1.0.0.tgz", 78 | "integrity": "sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==" 79 | }, 80 | "@phc/format": { 81 | "version": "0.5.0", 82 | "resolved": "https://registry.npmjs.org/@phc/format/-/format-0.5.0.tgz", 83 | "integrity": "sha512-JWtZ5P1bfXU0bAtTzCpOLYHDXuxSVdtL/oqz4+xa97h8w9E5IlVN333wugXVFv8vZ1hbXObKQf1ptXmFFcMByg==", 84 | "requires": { 85 | "safe-buffer": "^5.1.2" 86 | } 87 | }, 88 | "@types/aes-js": { 89 | "version": "3.1.1", 90 | "resolved": "https://registry.npmjs.org/@types/aes-js/-/aes-js-3.1.1.tgz", 91 | "integrity": "sha512-SDSGgXT3LRCH6qMWk8OHT1vLSVNuHNvCpKCx2/TYtQMbMGGgxJC9fspwSkQjqzRagrWnCrxuLL3jMNXLXHHvSw==", 92 | "dev": true 93 | }, 94 | "@types/bcryptjs": { 95 | "version": "2.4.2", 96 | "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.2.tgz", 97 | "integrity": "sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ==", 98 | "dev": true 99 | }, 100 | "@types/eccrypto": { 101 | "version": "1.1.1", 102 | "resolved": "https://registry.npmjs.org/@types/eccrypto/-/eccrypto-1.1.1.tgz", 103 | "integrity": "sha512-niDYN7XTQGKeH4+8C3vlzS7+rtTw40KTXUPd0IEscUOW2HbXMQME/TC7YJ1k8rnihvCUreQg6W2k5IsaXPxCzQ==", 104 | "dev": true, 105 | "requires": { 106 | "@types/expect": "^1.20.4", 107 | "@types/node": "*" 108 | } 109 | }, 110 | "@types/events": { 111 | "version": "3.0.0", 112 | "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", 113 | "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", 114 | "dev": true 115 | }, 116 | "@types/expect": { 117 | "version": "1.20.4", 118 | "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz", 119 | "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==", 120 | "dev": true 121 | }, 122 | "@types/fast-levenshtein": { 123 | "version": "0.0.1", 124 | "resolved": "https://registry.npmjs.org/@types/fast-levenshtein/-/fast-levenshtein-0.0.1.tgz", 125 | "integrity": "sha1-OjYVzxc2Rcj8pY0FHk4ygk5L0oY=", 126 | "dev": true 127 | }, 128 | "@types/glob": { 129 | "version": "7.1.1", 130 | "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", 131 | "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", 132 | "dev": true, 133 | "requires": { 134 | "@types/events": "*", 135 | "@types/minimatch": "*", 136 | "@types/node": "*" 137 | } 138 | }, 139 | "@types/mersenne-twister": { 140 | "version": "1.1.2", 141 | "resolved": "https://registry.npmjs.org/@types/mersenne-twister/-/mersenne-twister-1.1.2.tgz", 142 | "integrity": "sha512-7KMIfSkMpaVExbzJRLUXHMO4hkFWbbspHPREk8I6pBxiNN+3+l6eAEClMCIPIo2KjCkR0rjYfXppr6+wKdTwpA==", 143 | "dev": true 144 | }, 145 | "@types/minimatch": { 146 | "version": "3.0.3", 147 | "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", 148 | "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", 149 | "dev": true 150 | }, 151 | "@types/node": { 152 | "version": "12.12.39", 153 | "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.39.tgz", 154 | "integrity": "sha512-pADGfwnDkr6zagDwEiCVE4yQrv7XDkoeVa4OfA9Ju/zRTk6YNDLGtQbkdL4/56mCQQCs4AhNrBIag6jrp7ZuOg==", 155 | "dev": true 156 | }, 157 | "@types/node-forge": { 158 | "version": "0.9.3", 159 | "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-0.9.3.tgz", 160 | "integrity": "sha512-2ARlg50tba1Ps3Jg/D416LEWo9TxVACfuZLNy8GvLiggndLxxfUBz8OyeZZsE9JIF6r8AOJrcaKS3O/5NVhQlA==", 161 | "dev": true, 162 | "requires": { 163 | "@types/node": "*" 164 | } 165 | }, 166 | "@types/qrcode": { 167 | "version": "1.3.4", 168 | "resolved": "https://registry.npmjs.org/@types/qrcode/-/qrcode-1.3.4.tgz", 169 | "integrity": "sha512-aILE5yvKaqQXlY0YPMEYwK/KwdD43fwQTyagj0ffBBTQj8h//085Zp8LUrOnZ9FT69x64f5UgDo0EueY4BPAdg==", 170 | "dev": true, 171 | "requires": { 172 | "@types/node": "*" 173 | } 174 | }, 175 | "@types/uuid": { 176 | "version": "7.0.3", 177 | "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-7.0.3.tgz", 178 | "integrity": "sha512-PUdqTZVrNYTNcIhLHkiaYzoOIaUi5LFg/XLerAdgvwQrUCx+oSbtoBze1AMyvYbcwzUSNC+Isl58SM4Sm/6COw==", 179 | "dev": true 180 | }, 181 | "abbrev": { 182 | "version": "1.1.1", 183 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", 184 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" 185 | }, 186 | "acorn": { 187 | "version": "7.1.0", 188 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", 189 | "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==" 190 | }, 191 | "aes-js": { 192 | "version": "3.1.2", 193 | "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz", 194 | "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==" 195 | }, 196 | "ansi-regex": { 197 | "version": "2.1.1", 198 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 199 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" 200 | }, 201 | "ansi-styles": { 202 | "version": "3.2.1", 203 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 204 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 205 | "requires": { 206 | "color-convert": "^1.9.0" 207 | } 208 | }, 209 | "aproba": { 210 | "version": "1.2.0", 211 | "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", 212 | "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" 213 | }, 214 | "are-we-there-yet": { 215 | "version": "1.1.5", 216 | "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", 217 | "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", 218 | "requires": { 219 | "delegates": "^1.0.0", 220 | "readable-stream": "^2.0.6" 221 | } 222 | }, 223 | "arg": { 224 | "version": "4.1.3", 225 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", 226 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", 227 | "dev": true 228 | }, 229 | "argon2": { 230 | "version": "0.26.2", 231 | "resolved": "https://registry.npmjs.org/argon2/-/argon2-0.26.2.tgz", 232 | "integrity": "sha512-Tk9I/r3KIHCIHU5x2UawKsPi+g7MByAYnUZghXztQDXRp/997P31wa4qvdvokTaFBpsu6jOZACd+2qkBGGssRA==", 233 | "requires": { 234 | "@phc/format": "^0.5.0", 235 | "node-addon-api": "^2.0.0", 236 | "node-pre-gyp": "^0.14.0" 237 | } 238 | }, 239 | "array-union": { 240 | "version": "2.1.0", 241 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", 242 | "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", 243 | "dev": true 244 | }, 245 | "balanced-match": { 246 | "version": "1.0.0", 247 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 248 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 249 | }, 250 | "base64-js": { 251 | "version": "1.3.1", 252 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", 253 | "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" 254 | }, 255 | "bcryptjs": { 256 | "version": "2.4.3", 257 | "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", 258 | "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" 259 | }, 260 | "bindings": { 261 | "version": "1.5.0", 262 | "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", 263 | "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", 264 | "optional": true, 265 | "requires": { 266 | "file-uri-to-path": "1.0.0" 267 | } 268 | }, 269 | "bip66": { 270 | "version": "1.1.5", 271 | "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", 272 | "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", 273 | "optional": true, 274 | "requires": { 275 | "safe-buffer": "^5.0.1" 276 | } 277 | }, 278 | "bn.js": { 279 | "version": "4.11.8", 280 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", 281 | "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" 282 | }, 283 | "brace-expansion": { 284 | "version": "1.1.11", 285 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 286 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 287 | "requires": { 288 | "balanced-match": "^1.0.0", 289 | "concat-map": "0.0.1" 290 | } 291 | }, 292 | "braces": { 293 | "version": "3.0.2", 294 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 295 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 296 | "dev": true, 297 | "requires": { 298 | "fill-range": "^7.0.1" 299 | } 300 | }, 301 | "brorand": { 302 | "version": "1.1.0", 303 | "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", 304 | "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" 305 | }, 306 | "browserify-aes": { 307 | "version": "1.2.0", 308 | "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", 309 | "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", 310 | "optional": true, 311 | "requires": { 312 | "buffer-xor": "^1.0.3", 313 | "cipher-base": "^1.0.0", 314 | "create-hash": "^1.1.0", 315 | "evp_bytestokey": "^1.0.3", 316 | "inherits": "^2.0.1", 317 | "safe-buffer": "^5.0.1" 318 | } 319 | }, 320 | "buffer": { 321 | "version": "5.6.0", 322 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", 323 | "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", 324 | "requires": { 325 | "base64-js": "^1.0.2", 326 | "ieee754": "^1.1.4" 327 | } 328 | }, 329 | "buffer-alloc": { 330 | "version": "1.2.0", 331 | "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", 332 | "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", 333 | "requires": { 334 | "buffer-alloc-unsafe": "^1.1.0", 335 | "buffer-fill": "^1.0.0" 336 | } 337 | }, 338 | "buffer-alloc-unsafe": { 339 | "version": "1.1.0", 340 | "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", 341 | "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" 342 | }, 343 | "buffer-fill": { 344 | "version": "1.0.0", 345 | "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", 346 | "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" 347 | }, 348 | "buffer-from": { 349 | "version": "1.1.1", 350 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 351 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" 352 | }, 353 | "buffer-xor": { 354 | "version": "1.0.3", 355 | "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", 356 | "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", 357 | "optional": true 358 | }, 359 | "camelcase": { 360 | "version": "5.3.1", 361 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", 362 | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" 363 | }, 364 | "chownr": { 365 | "version": "1.1.4", 366 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", 367 | "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" 368 | }, 369 | "cipher-base": { 370 | "version": "1.0.4", 371 | "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", 372 | "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", 373 | "optional": true, 374 | "requires": { 375 | "inherits": "^2.0.1", 376 | "safe-buffer": "^5.0.1" 377 | } 378 | }, 379 | "cliui": { 380 | "version": "5.0.0", 381 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", 382 | "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", 383 | "requires": { 384 | "string-width": "^3.1.0", 385 | "strip-ansi": "^5.2.0", 386 | "wrap-ansi": "^5.1.0" 387 | }, 388 | "dependencies": { 389 | "ansi-regex": { 390 | "version": "4.1.0", 391 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 392 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" 393 | }, 394 | "is-fullwidth-code-point": { 395 | "version": "2.0.0", 396 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 397 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" 398 | }, 399 | "string-width": { 400 | "version": "3.1.0", 401 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 402 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 403 | "requires": { 404 | "emoji-regex": "^7.0.1", 405 | "is-fullwidth-code-point": "^2.0.0", 406 | "strip-ansi": "^5.1.0" 407 | } 408 | }, 409 | "strip-ansi": { 410 | "version": "5.2.0", 411 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 412 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 413 | "requires": { 414 | "ansi-regex": "^4.1.0" 415 | } 416 | } 417 | } 418 | }, 419 | "code-point-at": { 420 | "version": "1.1.0", 421 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", 422 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" 423 | }, 424 | "color-convert": { 425 | "version": "1.9.3", 426 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 427 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 428 | "requires": { 429 | "color-name": "1.1.3" 430 | } 431 | }, 432 | "color-name": { 433 | "version": "1.1.3", 434 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 435 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" 436 | }, 437 | "concat-map": { 438 | "version": "0.0.1", 439 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 440 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 441 | }, 442 | "console-control-strings": { 443 | "version": "1.1.0", 444 | "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", 445 | "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" 446 | }, 447 | "core-util-is": { 448 | "version": "1.0.2", 449 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 450 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 451 | }, 452 | "create-hash": { 453 | "version": "1.2.0", 454 | "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", 455 | "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", 456 | "optional": true, 457 | "requires": { 458 | "cipher-base": "^1.0.1", 459 | "inherits": "^2.0.1", 460 | "md5.js": "^1.3.4", 461 | "ripemd160": "^2.0.1", 462 | "sha.js": "^2.4.0" 463 | } 464 | }, 465 | "create-hmac": { 466 | "version": "1.1.7", 467 | "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", 468 | "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", 469 | "optional": true, 470 | "requires": { 471 | "cipher-base": "^1.0.3", 472 | "create-hash": "^1.1.0", 473 | "inherits": "^2.0.1", 474 | "ripemd160": "^2.0.0", 475 | "safe-buffer": "^5.0.1", 476 | "sha.js": "^2.4.8" 477 | } 478 | }, 479 | "dayjs": { 480 | "version": "1.8.26", 481 | "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.26.tgz", 482 | "integrity": "sha512-KqtAuIfdNfZR5sJY1Dixr2Is4ZvcCqhb0dZpCOt5dGEFiMzoIbjkTSzUb4QKTCsP+WNpGwUjAFIZrnZvUxxkhw==" 483 | }, 484 | "debug": { 485 | "version": "3.2.6", 486 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", 487 | "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", 488 | "requires": { 489 | "ms": "^2.1.1" 490 | } 491 | }, 492 | "decamelize": { 493 | "version": "1.2.0", 494 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 495 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" 496 | }, 497 | "deep-extend": { 498 | "version": "0.6.0", 499 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", 500 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" 501 | }, 502 | "delegates": { 503 | "version": "1.0.0", 504 | "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", 505 | "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" 506 | }, 507 | "detect-indent": { 508 | "version": "6.0.0", 509 | "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", 510 | "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==", 511 | "dev": true 512 | }, 513 | "detect-libc": { 514 | "version": "1.0.3", 515 | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", 516 | "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" 517 | }, 518 | "detect-newline": { 519 | "version": "3.1.0", 520 | "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", 521 | "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", 522 | "dev": true 523 | }, 524 | "diff": { 525 | "version": "4.0.2", 526 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 527 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", 528 | "dev": true 529 | }, 530 | "dijkstrajs": { 531 | "version": "1.0.1", 532 | "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz", 533 | "integrity": "sha1-082BIh4+pAdCz83lVtTpnpjdxxs=" 534 | }, 535 | "dir-glob": { 536 | "version": "3.0.1", 537 | "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", 538 | "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", 539 | "dev": true, 540 | "requires": { 541 | "path-type": "^4.0.0" 542 | } 543 | }, 544 | "drbg.js": { 545 | "version": "1.0.1", 546 | "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", 547 | "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", 548 | "optional": true, 549 | "requires": { 550 | "browserify-aes": "^1.0.6", 551 | "create-hash": "^1.1.2", 552 | "create-hmac": "^1.1.4" 553 | } 554 | }, 555 | "eccrypto": { 556 | "version": "1.1.3", 557 | "resolved": "https://registry.npmjs.org/eccrypto/-/eccrypto-1.1.3.tgz", 558 | "integrity": "sha512-Xtyj039Xp2NDZwoe9IcD7pT1EwM4DILdxPCN2H7Rk1wgJNtTkFpk+cpX1QpuHTMaIhkatOBlGGKzGw/DUCDdqg==", 559 | "requires": { 560 | "acorn": "7.1.0", 561 | "elliptic": "6.5.1", 562 | "es6-promise": "4.2.8", 563 | "nan": "2.14.0", 564 | "secp256k1": "3.7.1" 565 | }, 566 | "dependencies": { 567 | "elliptic": { 568 | "version": "6.5.1", 569 | "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.1.tgz", 570 | "integrity": "sha512-xvJINNLbTeWQjrl6X+7eQCrIy/YPv5XCpKW6kB5mKvtnGILoLDcySuwomfdzt0BMdLNVnuRNTuzKNHj0bva1Cg==", 571 | "requires": { 572 | "bn.js": "^4.4.0", 573 | "brorand": "^1.0.1", 574 | "hash.js": "^1.0.0", 575 | "hmac-drbg": "^1.0.0", 576 | "inherits": "^2.0.1", 577 | "minimalistic-assert": "^1.0.0", 578 | "minimalistic-crypto-utils": "^1.0.0" 579 | } 580 | } 581 | } 582 | }, 583 | "elliptic": { 584 | "version": "6.5.2", 585 | "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", 586 | "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", 587 | "optional": true, 588 | "requires": { 589 | "bn.js": "^4.4.0", 590 | "brorand": "^1.0.1", 591 | "hash.js": "^1.0.0", 592 | "hmac-drbg": "^1.0.0", 593 | "inherits": "^2.0.1", 594 | "minimalistic-assert": "^1.0.0", 595 | "minimalistic-crypto-utils": "^1.0.0" 596 | } 597 | }, 598 | "emoji-regex": { 599 | "version": "7.0.3", 600 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 601 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" 602 | }, 603 | "es6-promise": { 604 | "version": "4.2.8", 605 | "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", 606 | "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" 607 | }, 608 | "evp_bytestokey": { 609 | "version": "1.0.3", 610 | "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", 611 | "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", 612 | "optional": true, 613 | "requires": { 614 | "md5.js": "^1.3.4", 615 | "safe-buffer": "^5.1.1" 616 | } 617 | }, 618 | "fast-glob": { 619 | "version": "3.2.2", 620 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.2.tgz", 621 | "integrity": "sha512-UDV82o4uQyljznxwMxyVRJgZZt3O5wENYojjzbaGEGZgeOxkLFf+V4cnUD+krzb2F72E18RhamkMZ7AdeggF7A==", 622 | "dev": true, 623 | "requires": { 624 | "@nodelib/fs.stat": "^2.0.2", 625 | "@nodelib/fs.walk": "^1.2.3", 626 | "glob-parent": "^5.1.0", 627 | "merge2": "^1.3.0", 628 | "micromatch": "^4.0.2", 629 | "picomatch": "^2.2.1" 630 | } 631 | }, 632 | "fast-levenshtein": { 633 | "version": "2.0.6", 634 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 635 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" 636 | }, 637 | "fastq": { 638 | "version": "1.8.0", 639 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", 640 | "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", 641 | "dev": true, 642 | "requires": { 643 | "reusify": "^1.0.4" 644 | } 645 | }, 646 | "file-uri-to-path": { 647 | "version": "1.0.0", 648 | "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", 649 | "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", 650 | "optional": true 651 | }, 652 | "fill-range": { 653 | "version": "7.0.1", 654 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 655 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 656 | "dev": true, 657 | "requires": { 658 | "to-regex-range": "^5.0.1" 659 | } 660 | }, 661 | "find-up": { 662 | "version": "3.0.0", 663 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", 664 | "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", 665 | "requires": { 666 | "locate-path": "^3.0.0" 667 | } 668 | }, 669 | "fs-minipass": { 670 | "version": "1.2.7", 671 | "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", 672 | "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", 673 | "requires": { 674 | "minipass": "^2.6.0" 675 | } 676 | }, 677 | "fs.realpath": { 678 | "version": "1.0.0", 679 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 680 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 681 | }, 682 | "gauge": { 683 | "version": "2.7.4", 684 | "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", 685 | "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", 686 | "requires": { 687 | "aproba": "^1.0.3", 688 | "console-control-strings": "^1.0.0", 689 | "has-unicode": "^2.0.0", 690 | "object-assign": "^4.1.0", 691 | "signal-exit": "^3.0.0", 692 | "string-width": "^1.0.1", 693 | "strip-ansi": "^3.0.1", 694 | "wide-align": "^1.1.0" 695 | } 696 | }, 697 | "get-caller-file": { 698 | "version": "2.0.5", 699 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 700 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" 701 | }, 702 | "git-hooks-list": { 703 | "version": "1.0.3", 704 | "resolved": "https://registry.npmjs.org/git-hooks-list/-/git-hooks-list-1.0.3.tgz", 705 | "integrity": "sha512-Y7wLWcrLUXwk2noSka166byGCvhMtDRpgHdzCno1UQv/n/Hegp++a2xBWJL1lJarnKD3SWaljD+0z1ztqxuKyQ==", 706 | "dev": true 707 | }, 708 | "glob": { 709 | "version": "7.1.6", 710 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 711 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 712 | "requires": { 713 | "fs.realpath": "^1.0.0", 714 | "inflight": "^1.0.4", 715 | "inherits": "2", 716 | "minimatch": "^3.0.4", 717 | "once": "^1.3.0", 718 | "path-is-absolute": "^1.0.0" 719 | } 720 | }, 721 | "glob-parent": { 722 | "version": "5.1.1", 723 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", 724 | "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", 725 | "dev": true, 726 | "requires": { 727 | "is-glob": "^4.0.1" 728 | } 729 | }, 730 | "globby": { 731 | "version": "10.0.0", 732 | "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.0.tgz", 733 | "integrity": "sha512-3LifW9M4joGZasyYPz2A1U74zbC/45fvpXUvO/9KbSa+VV0aGZarWkfdgKyR9sExNP0t0x0ss/UMJpNpcaTspw==", 734 | "dev": true, 735 | "requires": { 736 | "@types/glob": "^7.1.1", 737 | "array-union": "^2.1.0", 738 | "dir-glob": "^3.0.1", 739 | "fast-glob": "^3.0.3", 740 | "glob": "^7.1.3", 741 | "ignore": "^5.1.1", 742 | "merge2": "^1.2.3", 743 | "slash": "^3.0.0" 744 | } 745 | }, 746 | "has-unicode": { 747 | "version": "2.0.1", 748 | "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", 749 | "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" 750 | }, 751 | "hash-base": { 752 | "version": "3.1.0", 753 | "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", 754 | "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", 755 | "optional": true, 756 | "requires": { 757 | "inherits": "^2.0.4", 758 | "readable-stream": "^3.6.0", 759 | "safe-buffer": "^5.2.0" 760 | }, 761 | "dependencies": { 762 | "readable-stream": { 763 | "version": "3.6.0", 764 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", 765 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", 766 | "optional": true, 767 | "requires": { 768 | "inherits": "^2.0.3", 769 | "string_decoder": "^1.1.1", 770 | "util-deprecate": "^1.0.1" 771 | } 772 | } 773 | } 774 | }, 775 | "hash.js": { 776 | "version": "1.1.7", 777 | "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", 778 | "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", 779 | "requires": { 780 | "inherits": "^2.0.3", 781 | "minimalistic-assert": "^1.0.1" 782 | } 783 | }, 784 | "hmac-drbg": { 785 | "version": "1.0.1", 786 | "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", 787 | "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", 788 | "requires": { 789 | "hash.js": "^1.0.3", 790 | "minimalistic-assert": "^1.0.0", 791 | "minimalistic-crypto-utils": "^1.0.1" 792 | } 793 | }, 794 | "iconv-lite": { 795 | "version": "0.4.24", 796 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 797 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 798 | "requires": { 799 | "safer-buffer": ">= 2.1.2 < 3" 800 | } 801 | }, 802 | "ieee754": { 803 | "version": "1.1.13", 804 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", 805 | "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" 806 | }, 807 | "ignore": { 808 | "version": "5.1.4", 809 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", 810 | "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", 811 | "dev": true 812 | }, 813 | "ignore-walk": { 814 | "version": "3.0.3", 815 | "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", 816 | "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", 817 | "requires": { 818 | "minimatch": "^3.0.4" 819 | } 820 | }, 821 | "inflight": { 822 | "version": "1.0.6", 823 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 824 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 825 | "requires": { 826 | "once": "^1.3.0", 827 | "wrappy": "1" 828 | } 829 | }, 830 | "inherits": { 831 | "version": "2.0.4", 832 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 833 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 834 | }, 835 | "ini": { 836 | "version": "1.3.5", 837 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", 838 | "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" 839 | }, 840 | "is-extglob": { 841 | "version": "2.1.1", 842 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 843 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 844 | "dev": true 845 | }, 846 | "is-fullwidth-code-point": { 847 | "version": "1.0.0", 848 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 849 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", 850 | "requires": { 851 | "number-is-nan": "^1.0.0" 852 | } 853 | }, 854 | "is-glob": { 855 | "version": "4.0.1", 856 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 857 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 858 | "dev": true, 859 | "requires": { 860 | "is-extglob": "^2.1.1" 861 | } 862 | }, 863 | "is-number": { 864 | "version": "7.0.0", 865 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 866 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 867 | "dev": true 868 | }, 869 | "is-plain-obj": { 870 | "version": "2.1.0", 871 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", 872 | "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", 873 | "dev": true 874 | }, 875 | "isarray": { 876 | "version": "1.0.0", 877 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 878 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 879 | }, 880 | "jose": { 881 | "version": "1.27.0", 882 | "resolved": "https://registry.npmjs.org/jose/-/jose-1.27.0.tgz", 883 | "integrity": "sha512-SxYPCM9pWDaK070CXbxgL4ktVzLlE0yJxevDJtbWxv2WMQwYfpBZLYlG8PhChsiOfOXp6FrceRgTuZh1vZeDlg==", 884 | "requires": { 885 | "@panva/asn1.js": "^1.0.0" 886 | } 887 | }, 888 | "jssha": { 889 | "version": "3.1.0", 890 | "resolved": "https://registry.npmjs.org/jssha/-/jssha-3.1.0.tgz", 891 | "integrity": "sha512-tPCmr8xSLd8ug6N51k0rbF1tAQWZz1i/uCVHpCH9dl+Te+wM/T375R3lTexP3bk1HPmQ+NlJHQPYLmYuyk6slA==" 892 | }, 893 | "locate-path": { 894 | "version": "3.0.0", 895 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", 896 | "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", 897 | "requires": { 898 | "p-locate": "^3.0.0", 899 | "path-exists": "^3.0.0" 900 | } 901 | }, 902 | "make-error": { 903 | "version": "1.3.6", 904 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", 905 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", 906 | "dev": true 907 | }, 908 | "md5.js": { 909 | "version": "1.3.5", 910 | "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", 911 | "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", 912 | "optional": true, 913 | "requires": { 914 | "hash-base": "^3.0.0", 915 | "inherits": "^2.0.1", 916 | "safe-buffer": "^5.1.2" 917 | } 918 | }, 919 | "merge2": { 920 | "version": "1.3.0", 921 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", 922 | "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==", 923 | "dev": true 924 | }, 925 | "mersenne-twister": { 926 | "version": "1.1.0", 927 | "resolved": "https://registry.npmjs.org/mersenne-twister/-/mersenne-twister-1.1.0.tgz", 928 | "integrity": "sha1-+RZhjuQ9cXnvz2Qb7EUx65Zwl4o=" 929 | }, 930 | "micromatch": { 931 | "version": "4.0.2", 932 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", 933 | "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", 934 | "dev": true, 935 | "requires": { 936 | "braces": "^3.0.1", 937 | "picomatch": "^2.0.5" 938 | } 939 | }, 940 | "minimalistic-assert": { 941 | "version": "1.0.1", 942 | "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", 943 | "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" 944 | }, 945 | "minimalistic-crypto-utils": { 946 | "version": "1.0.1", 947 | "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", 948 | "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" 949 | }, 950 | "minimatch": { 951 | "version": "3.0.4", 952 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 953 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 954 | "requires": { 955 | "brace-expansion": "^1.1.7" 956 | } 957 | }, 958 | "minimist": { 959 | "version": "1.2.5", 960 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 961 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" 962 | }, 963 | "minipass": { 964 | "version": "2.9.0", 965 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", 966 | "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", 967 | "requires": { 968 | "safe-buffer": "^5.1.2", 969 | "yallist": "^3.0.0" 970 | } 971 | }, 972 | "minizlib": { 973 | "version": "1.3.3", 974 | "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", 975 | "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", 976 | "requires": { 977 | "minipass": "^2.9.0" 978 | } 979 | }, 980 | "mkdirp": { 981 | "version": "0.5.5", 982 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", 983 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", 984 | "requires": { 985 | "minimist": "^1.2.5" 986 | } 987 | }, 988 | "ms": { 989 | "version": "2.1.2", 990 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 991 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 992 | }, 993 | "nan": { 994 | "version": "2.14.0", 995 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", 996 | "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" 997 | }, 998 | "needle": { 999 | "version": "2.4.1", 1000 | "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.1.tgz", 1001 | "integrity": "sha512-x/gi6ijr4B7fwl6WYL9FwlCvRQKGlUNvnceho8wxkwXqN8jvVmmmATTmZPRRG7b/yC1eode26C2HO9jl78Du9g==", 1002 | "requires": { 1003 | "debug": "^3.2.6", 1004 | "iconv-lite": "^0.4.4", 1005 | "sax": "^1.2.4" 1006 | } 1007 | }, 1008 | "node-addon-api": { 1009 | "version": "2.0.0", 1010 | "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.0.tgz", 1011 | "integrity": "sha512-ASCL5U13as7HhOExbT6OlWJJUV/lLzL2voOSP1UVehpRD8FbSrSDjfScK/KwAvVTI5AS6r4VwbOMlIqtvRidnA==" 1012 | }, 1013 | "node-forge": { 1014 | "version": "0.9.1", 1015 | "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.1.tgz", 1016 | "integrity": "sha512-G6RlQt5Sb4GMBzXvhfkeFmbqR6MzhtnT7VTHuLadjkii3rdYHNdw0m8zA4BTxVIh68FicCQ2NSUANpsqkr9jvQ==" 1017 | }, 1018 | "node-pre-gyp": { 1019 | "version": "0.14.0", 1020 | "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz", 1021 | "integrity": "sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA==", 1022 | "requires": { 1023 | "detect-libc": "^1.0.2", 1024 | "mkdirp": "^0.5.1", 1025 | "needle": "^2.2.1", 1026 | "nopt": "^4.0.1", 1027 | "npm-packlist": "^1.1.6", 1028 | "npmlog": "^4.0.2", 1029 | "rc": "^1.2.7", 1030 | "rimraf": "^2.6.1", 1031 | "semver": "^5.3.0", 1032 | "tar": "^4.4.2" 1033 | } 1034 | }, 1035 | "nopt": { 1036 | "version": "4.0.3", 1037 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", 1038 | "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", 1039 | "requires": { 1040 | "abbrev": "1", 1041 | "osenv": "^0.1.4" 1042 | } 1043 | }, 1044 | "npm-bundled": { 1045 | "version": "1.1.1", 1046 | "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", 1047 | "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", 1048 | "requires": { 1049 | "npm-normalize-package-bin": "^1.0.1" 1050 | } 1051 | }, 1052 | "npm-normalize-package-bin": { 1053 | "version": "1.0.1", 1054 | "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", 1055 | "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==" 1056 | }, 1057 | "npm-packlist": { 1058 | "version": "1.4.8", 1059 | "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", 1060 | "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", 1061 | "requires": { 1062 | "ignore-walk": "^3.0.1", 1063 | "npm-bundled": "^1.0.1", 1064 | "npm-normalize-package-bin": "^1.0.1" 1065 | } 1066 | }, 1067 | "npmlog": { 1068 | "version": "4.1.2", 1069 | "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", 1070 | "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", 1071 | "requires": { 1072 | "are-we-there-yet": "~1.1.2", 1073 | "console-control-strings": "~1.1.0", 1074 | "gauge": "~2.7.3", 1075 | "set-blocking": "~2.0.0" 1076 | } 1077 | }, 1078 | "number-is-nan": { 1079 | "version": "1.0.1", 1080 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 1081 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" 1082 | }, 1083 | "object-assign": { 1084 | "version": "4.1.1", 1085 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1086 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 1087 | }, 1088 | "once": { 1089 | "version": "1.4.0", 1090 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1091 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1092 | "requires": { 1093 | "wrappy": "1" 1094 | } 1095 | }, 1096 | "os-homedir": { 1097 | "version": "1.0.2", 1098 | "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", 1099 | "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" 1100 | }, 1101 | "os-tmpdir": { 1102 | "version": "1.0.2", 1103 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 1104 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" 1105 | }, 1106 | "osenv": { 1107 | "version": "0.1.5", 1108 | "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", 1109 | "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", 1110 | "requires": { 1111 | "os-homedir": "^1.0.0", 1112 | "os-tmpdir": "^1.0.0" 1113 | } 1114 | }, 1115 | "otplib": { 1116 | "version": "12.0.1", 1117 | "resolved": "https://registry.npmjs.org/otplib/-/otplib-12.0.1.tgz", 1118 | "integrity": "sha512-xDGvUOQjop7RDgxTQ+o4pOol0/3xSZzawTiPKRrHnQWAy0WjhNs/5HdIDJCrqC4MBynmjXgULc6YfioaxZeFgg==", 1119 | "requires": { 1120 | "@otplib/core": "^12.0.1", 1121 | "@otplib/preset-default": "^12.0.1", 1122 | "@otplib/preset-v11": "^12.0.1" 1123 | } 1124 | }, 1125 | "p-limit": { 1126 | "version": "2.3.0", 1127 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", 1128 | "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", 1129 | "requires": { 1130 | "p-try": "^2.0.0" 1131 | } 1132 | }, 1133 | "p-locate": { 1134 | "version": "3.0.0", 1135 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", 1136 | "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", 1137 | "requires": { 1138 | "p-limit": "^2.0.0" 1139 | } 1140 | }, 1141 | "p-try": { 1142 | "version": "2.2.0", 1143 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", 1144 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" 1145 | }, 1146 | "path-exists": { 1147 | "version": "3.0.0", 1148 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 1149 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" 1150 | }, 1151 | "path-is-absolute": { 1152 | "version": "1.0.1", 1153 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1154 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 1155 | }, 1156 | "path-type": { 1157 | "version": "4.0.0", 1158 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", 1159 | "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", 1160 | "dev": true 1161 | }, 1162 | "picomatch": { 1163 | "version": "2.2.2", 1164 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", 1165 | "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", 1166 | "dev": true 1167 | }, 1168 | "pngjs": { 1169 | "version": "3.4.0", 1170 | "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", 1171 | "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==" 1172 | }, 1173 | "process-nextick-args": { 1174 | "version": "2.0.1", 1175 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 1176 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 1177 | }, 1178 | "qrcode": { 1179 | "version": "1.4.4", 1180 | "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.4.4.tgz", 1181 | "integrity": "sha512-oLzEC5+NKFou9P0bMj5+v6Z40evexeE29Z9cummZXZ9QXyMr3lphkURzxjXgPJC5azpxcshoDWV1xE46z+/c3Q==", 1182 | "requires": { 1183 | "buffer": "^5.4.3", 1184 | "buffer-alloc": "^1.2.0", 1185 | "buffer-from": "^1.1.1", 1186 | "dijkstrajs": "^1.0.1", 1187 | "isarray": "^2.0.1", 1188 | "pngjs": "^3.3.0", 1189 | "yargs": "^13.2.4" 1190 | }, 1191 | "dependencies": { 1192 | "isarray": { 1193 | "version": "2.0.5", 1194 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", 1195 | "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" 1196 | } 1197 | } 1198 | }, 1199 | "rc": { 1200 | "version": "1.2.8", 1201 | "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", 1202 | "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", 1203 | "requires": { 1204 | "deep-extend": "^0.6.0", 1205 | "ini": "~1.3.0", 1206 | "minimist": "^1.2.0", 1207 | "strip-json-comments": "~2.0.1" 1208 | } 1209 | }, 1210 | "readable-stream": { 1211 | "version": "2.3.7", 1212 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 1213 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 1214 | "requires": { 1215 | "core-util-is": "~1.0.0", 1216 | "inherits": "~2.0.3", 1217 | "isarray": "~1.0.0", 1218 | "process-nextick-args": "~2.0.0", 1219 | "safe-buffer": "~5.1.1", 1220 | "string_decoder": "~1.1.1", 1221 | "util-deprecate": "~1.0.1" 1222 | }, 1223 | "dependencies": { 1224 | "safe-buffer": { 1225 | "version": "5.1.2", 1226 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1227 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 1228 | } 1229 | } 1230 | }, 1231 | "require-directory": { 1232 | "version": "2.1.1", 1233 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 1234 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" 1235 | }, 1236 | "require-main-filename": { 1237 | "version": "2.0.0", 1238 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", 1239 | "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" 1240 | }, 1241 | "reusify": { 1242 | "version": "1.0.4", 1243 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 1244 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 1245 | "dev": true 1246 | }, 1247 | "rimraf": { 1248 | "version": "2.7.1", 1249 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", 1250 | "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", 1251 | "requires": { 1252 | "glob": "^7.1.3" 1253 | } 1254 | }, 1255 | "ripemd160": { 1256 | "version": "2.0.2", 1257 | "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", 1258 | "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", 1259 | "optional": true, 1260 | "requires": { 1261 | "hash-base": "^3.0.0", 1262 | "inherits": "^2.0.1" 1263 | } 1264 | }, 1265 | "run-parallel": { 1266 | "version": "1.1.9", 1267 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", 1268 | "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", 1269 | "dev": true 1270 | }, 1271 | "safe-buffer": { 1272 | "version": "5.2.0", 1273 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", 1274 | "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" 1275 | }, 1276 | "safer-buffer": { 1277 | "version": "2.1.2", 1278 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1279 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1280 | }, 1281 | "sax": { 1282 | "version": "1.2.4", 1283 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", 1284 | "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" 1285 | }, 1286 | "secp256k1": { 1287 | "version": "3.7.1", 1288 | "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz", 1289 | "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==", 1290 | "optional": true, 1291 | "requires": { 1292 | "bindings": "^1.5.0", 1293 | "bip66": "^1.1.5", 1294 | "bn.js": "^4.11.8", 1295 | "create-hash": "^1.2.0", 1296 | "drbg.js": "^1.0.1", 1297 | "elliptic": "^6.4.1", 1298 | "nan": "^2.14.0", 1299 | "safe-buffer": "^5.1.2" 1300 | } 1301 | }, 1302 | "semver": { 1303 | "version": "5.7.1", 1304 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 1305 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" 1306 | }, 1307 | "set-blocking": { 1308 | "version": "2.0.0", 1309 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 1310 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" 1311 | }, 1312 | "sha.js": { 1313 | "version": "2.4.11", 1314 | "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", 1315 | "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", 1316 | "optional": true, 1317 | "requires": { 1318 | "inherits": "^2.0.1", 1319 | "safe-buffer": "^5.0.1" 1320 | } 1321 | }, 1322 | "signal-exit": { 1323 | "version": "3.0.3", 1324 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", 1325 | "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" 1326 | }, 1327 | "slash": { 1328 | "version": "3.0.0", 1329 | "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", 1330 | "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", 1331 | "dev": true 1332 | }, 1333 | "sort-object-keys": { 1334 | "version": "1.1.3", 1335 | "resolved": "https://registry.npmjs.org/sort-object-keys/-/sort-object-keys-1.1.3.tgz", 1336 | "integrity": "sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==", 1337 | "dev": true 1338 | }, 1339 | "sort-package-json": { 1340 | "version": "1.42.2", 1341 | "resolved": "https://registry.npmjs.org/sort-package-json/-/sort-package-json-1.42.2.tgz", 1342 | "integrity": "sha512-B4cIYKeBdNUJXHPxe0G+x3uHHpSWSgJ3z62+W1C28wT1whkEhrz/B3r9lSyW+VVhz1rc+ymGmNkr1mJ323w0xQ==", 1343 | "dev": true, 1344 | "requires": { 1345 | "detect-indent": "^6.0.0", 1346 | "detect-newline": "3.1.0", 1347 | "git-hooks-list": "1.0.3", 1348 | "globby": "10.0.0", 1349 | "is-plain-obj": "2.1.0", 1350 | "sort-object-keys": "^1.1.3" 1351 | } 1352 | }, 1353 | "source-map": { 1354 | "version": "0.6.1", 1355 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1356 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 1357 | "dev": true 1358 | }, 1359 | "source-map-support": { 1360 | "version": "0.5.19", 1361 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", 1362 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", 1363 | "dev": true, 1364 | "requires": { 1365 | "buffer-from": "^1.0.0", 1366 | "source-map": "^0.6.0" 1367 | } 1368 | }, 1369 | "string-width": { 1370 | "version": "1.0.2", 1371 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 1372 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", 1373 | "requires": { 1374 | "code-point-at": "^1.0.0", 1375 | "is-fullwidth-code-point": "^1.0.0", 1376 | "strip-ansi": "^3.0.0" 1377 | } 1378 | }, 1379 | "string_decoder": { 1380 | "version": "1.1.1", 1381 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 1382 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 1383 | "requires": { 1384 | "safe-buffer": "~5.1.0" 1385 | }, 1386 | "dependencies": { 1387 | "safe-buffer": { 1388 | "version": "5.1.2", 1389 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1390 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 1391 | } 1392 | } 1393 | }, 1394 | "strip-ansi": { 1395 | "version": "3.0.1", 1396 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 1397 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 1398 | "requires": { 1399 | "ansi-regex": "^2.0.0" 1400 | } 1401 | }, 1402 | "strip-json-comments": { 1403 | "version": "2.0.1", 1404 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 1405 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" 1406 | }, 1407 | "tar": { 1408 | "version": "4.4.13", 1409 | "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", 1410 | "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", 1411 | "requires": { 1412 | "chownr": "^1.1.1", 1413 | "fs-minipass": "^1.2.5", 1414 | "minipass": "^2.8.6", 1415 | "minizlib": "^1.2.1", 1416 | "mkdirp": "^0.5.0", 1417 | "safe-buffer": "^5.1.2", 1418 | "yallist": "^3.0.3" 1419 | } 1420 | }, 1421 | "thirty-two": { 1422 | "version": "1.0.2", 1423 | "resolved": "https://registry.npmjs.org/thirty-two/-/thirty-two-1.0.2.tgz", 1424 | "integrity": "sha1-TKL//AKlEpDSdEueP1V2k8prYno=" 1425 | }, 1426 | "to-regex-range": { 1427 | "version": "5.0.1", 1428 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1429 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1430 | "dev": true, 1431 | "requires": { 1432 | "is-number": "^7.0.0" 1433 | } 1434 | }, 1435 | "ts-node": { 1436 | "version": "8.10.1", 1437 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.1.tgz", 1438 | "integrity": "sha512-bdNz1L4ekHiJul6SHtZWs1ujEKERJnHs4HxN7rjTyyVOFf3HaJ6sLqe6aPG62XTzAB/63pKRh5jTSWL0D7bsvw==", 1439 | "dev": true, 1440 | "requires": { 1441 | "arg": "^4.1.0", 1442 | "diff": "^4.0.1", 1443 | "make-error": "^1.1.1", 1444 | "source-map-support": "^0.5.17", 1445 | "yn": "3.1.1" 1446 | } 1447 | }, 1448 | "typescript": { 1449 | "version": "3.9.2", 1450 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.2.tgz", 1451 | "integrity": "sha512-q2ktq4n/uLuNNShyayit+DTobV2ApPEo/6so68JaD5ojvc/6GClBipedB9zNWYxRSAlZXAe405Rlijzl6qDiSw==", 1452 | "dev": true 1453 | }, 1454 | "util-deprecate": { 1455 | "version": "1.0.2", 1456 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1457 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 1458 | }, 1459 | "uuid": { 1460 | "version": "8.0.0", 1461 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", 1462 | "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==" 1463 | }, 1464 | "which-module": { 1465 | "version": "2.0.0", 1466 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", 1467 | "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" 1468 | }, 1469 | "wide-align": { 1470 | "version": "1.1.3", 1471 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", 1472 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", 1473 | "requires": { 1474 | "string-width": "^1.0.2 || 2" 1475 | } 1476 | }, 1477 | "wrap-ansi": { 1478 | "version": "5.1.0", 1479 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", 1480 | "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", 1481 | "requires": { 1482 | "ansi-styles": "^3.2.0", 1483 | "string-width": "^3.0.0", 1484 | "strip-ansi": "^5.0.0" 1485 | }, 1486 | "dependencies": { 1487 | "ansi-regex": { 1488 | "version": "4.1.0", 1489 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 1490 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" 1491 | }, 1492 | "is-fullwidth-code-point": { 1493 | "version": "2.0.0", 1494 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1495 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" 1496 | }, 1497 | "string-width": { 1498 | "version": "3.1.0", 1499 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 1500 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 1501 | "requires": { 1502 | "emoji-regex": "^7.0.1", 1503 | "is-fullwidth-code-point": "^2.0.0", 1504 | "strip-ansi": "^5.1.0" 1505 | } 1506 | }, 1507 | "strip-ansi": { 1508 | "version": "5.2.0", 1509 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 1510 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 1511 | "requires": { 1512 | "ansi-regex": "^4.1.0" 1513 | } 1514 | } 1515 | } 1516 | }, 1517 | "wrappy": { 1518 | "version": "1.0.2", 1519 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1520 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 1521 | }, 1522 | "y18n": { 1523 | "version": "4.0.0", 1524 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", 1525 | "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" 1526 | }, 1527 | "yallist": { 1528 | "version": "3.1.1", 1529 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", 1530 | "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" 1531 | }, 1532 | "yargs": { 1533 | "version": "13.3.2", 1534 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", 1535 | "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", 1536 | "requires": { 1537 | "cliui": "^5.0.0", 1538 | "find-up": "^3.0.0", 1539 | "get-caller-file": "^2.0.1", 1540 | "require-directory": "^2.1.1", 1541 | "require-main-filename": "^2.0.0", 1542 | "set-blocking": "^2.0.0", 1543 | "string-width": "^3.0.0", 1544 | "which-module": "^2.0.0", 1545 | "y18n": "^4.0.0", 1546 | "yargs-parser": "^13.1.2" 1547 | }, 1548 | "dependencies": { 1549 | "ansi-regex": { 1550 | "version": "4.1.0", 1551 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 1552 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" 1553 | }, 1554 | "is-fullwidth-code-point": { 1555 | "version": "2.0.0", 1556 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1557 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" 1558 | }, 1559 | "string-width": { 1560 | "version": "3.1.0", 1561 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 1562 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 1563 | "requires": { 1564 | "emoji-regex": "^7.0.1", 1565 | "is-fullwidth-code-point": "^2.0.0", 1566 | "strip-ansi": "^5.1.0" 1567 | } 1568 | }, 1569 | "strip-ansi": { 1570 | "version": "5.2.0", 1571 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 1572 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 1573 | "requires": { 1574 | "ansi-regex": "^4.1.0" 1575 | } 1576 | } 1577 | } 1578 | }, 1579 | "yargs-parser": { 1580 | "version": "13.1.2", 1581 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", 1582 | "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", 1583 | "requires": { 1584 | "camelcase": "^5.0.0", 1585 | "decamelize": "^1.2.0" 1586 | } 1587 | }, 1588 | "yn": { 1589 | "version": "3.1.1", 1590 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", 1591 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", 1592 | "dev": true 1593 | } 1594 | } 1595 | } 1596 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cryptography-course", 3 | "version": "1.0.0", 4 | "private": true, 5 | "description": "Sample code for cryptography course", 6 | "license": "MIT", 7 | "author": "Yao-Siang Su", 8 | "main": "index.js", 9 | "scripts": { 10 | "sort-package.json": "npx sort-package-json ./package.json", 11 | "test": "echo \"Error: no test specified\" && exit 1" 12 | }, 13 | "dependencies": { 14 | "aes-js": "^3.1.2", 15 | "argon2": "^0.26.2", 16 | "bcryptjs": "^2.4.3", 17 | "dayjs": "^1.8.26", 18 | "eccrypto": "^1.1.3", 19 | "fast-levenshtein": "^2.0.6", 20 | "jose": "^1.27.0", 21 | "jssha": "^3.1.0", 22 | "mersenne-twister": "^1.1.0", 23 | "node-forge": "^0.9.1", 24 | "otplib": "^12.0.1", 25 | "qrcode": "^1.4.4", 26 | "uuid": "^8.0.0" 27 | }, 28 | "devDependencies": { 29 | "@types/aes-js": "^3.1.1", 30 | "@types/bcryptjs": "^2.4.2", 31 | "@types/eccrypto": "^1.1.1", 32 | "@types/fast-levenshtein": "0.0.1", 33 | "@types/mersenne-twister": "^1.1.2", 34 | "@types/node": "^12.12.39", 35 | "@types/node-forge": "^0.9.3", 36 | "@types/qrcode": "^1.3.4", 37 | "@types/uuid": "^7.0.3", 38 | "sort-package-json": "^1.42.2", 39 | "ts-node": "^8.10.1", 40 | "typescript": "^3.8.3" 41 | }, 42 | "engines": { 43 | "node": ">= 12.0.0" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | // "incremental": true, /* Enable incremental compilation */ 5 | "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ 6 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ 7 | // "lib": [], /* Specify library files to be included in the compilation. */ 8 | // "allowJs": true, /* Allow javascript files to be compiled. */ 9 | // "checkJs": true, /* Report errors in .js files. */ 10 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 11 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 12 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 13 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 14 | // "outFile": "./", /* Concatenate and emit output to single file. */ 15 | // "outDir": "./", /* Redirect output structure to the directory. */ 16 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 17 | // "composite": true, /* Enable project compilation */ 18 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 19 | // "removeComments": true, /* Do not emit comments to output. */ 20 | // "noEmit": true, /* Do not emit outputs. */ 21 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 22 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 23 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 24 | 25 | /* Strict Type-Checking Options */ 26 | "strict": true, /* Enable all strict type-checking options. */ 27 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 28 | // "strictNullChecks": true, /* Enable strict null checks. */ 29 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 30 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 31 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 32 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 33 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 34 | 35 | /* Additional Checks */ 36 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 37 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 38 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 39 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 40 | 41 | /* Module Resolution Options */ 42 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 43 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 44 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 45 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 46 | // "typeRoots": [], /* List of folders to include type definitions from. */ 47 | // "types": [], /* Type declaration files to be included in compilation. */ 48 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 49 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 50 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 51 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 52 | 53 | /* Source Map Options */ 54 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 55 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 56 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 57 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 58 | 59 | /* Experimental Options */ 60 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 61 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 62 | 63 | /* Advanced Options */ 64 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ 65 | } 66 | } 67 | --------------------------------------------------------------------------------