UNPKG

cripta

Version:

A layer of encryption a little too judicious

212 lines (171 loc) 6.59 kB
// import crypto from 'node:crypto' // import { Config } from './config' // import { TYPE, AcceptedValue, ConfigOptions } from './types' // import { UrlSafeBase64 } from '@/base64' // import { sha256 } from '@/hash' // export class Factory { // private separator = '\x1f' // private encoding: BufferEncoding = 'utf8' // public config: Config = new Config() // public lastConfig: Config | null = null // constructor(config?: ConfigOptions | Config) { // config && this.setConfig(config) // } // public same(): this { // this.config.entropy = 0 // return this.setConfig(this.config) // } // public unique(): this { // this.config.entropy = 4 // return this.setConfig(this.config) // } // public setConfig(config: ConfigOptions | Config): this { // if (!(config instanceof Config)) config = new Config(config) // this.config = Object.assign(new Config(), config) // return this // } // public onceConfig(config: ConfigOptions | Config): this { // if (!(config instanceof Config)) config = new Config(config) // this.lastConfig = this.config // this.config = Object.assign(new Config(), config) // return this // } // public onceKey(secret: string): this { // this.lastConfig = Object.assign(new Config(), this.config) // this.config.key = secret // return this // } // private maybeRestoreConfig(): this { // if (this.lastConfig !== null) { // this.config = Object.assign(new Config(), this.lastConfig) // this.lastConfig = null // } // return this // } // private validateConfig(): void { // const key = this.config.key // if (typeof key !== 'string' || !key.trim()) // throw new Error('Secret key is required for use cripta.') // } // public encode(data: AcceptedValue): string { // this.validateConfig() // const entropyInt = this.config.getInt('entropy') // const entropy = entropyInt ? crypto.randomBytes(entropyInt).toString('binary') : '' // const payload = this.toText(data) // const encoded = this.baseEncode(this.cipher( // payload, this.forgeKey(entropy) // ) + entropy) // this.maybeRestoreConfig() // return encoded // } // public decode(data: string): AcceptedValue { // this.validateConfig() // const binary = this.baseDecode(data) // const eLength = this.config.getInt('entropy') // const entropy = binary.slice(-eLength) // const decoded = this.convert(this.cipher( // // binary.substring(0, binary.length - eLength), // binary.slice(0, -eLength), // this.forgeKey(entropy) // )) // this.maybeRestoreConfig() // return decoded // } // private convert(value: string): AcceptedValue { // const separatorIndex = value.indexOf(this.separator) // if (separatorIndex !== -1) { // const typeStr = value.substring(0, separatorIndex) // const typeNum = parseInt(typeStr, 10) // const data = value.substring(separatorIndex + 1) // switch (typeNum) { // case TYPE.null: return null // case TYPE.boolean: return data === 'true' || data === '1' // case TYPE.string: return data // case TYPE.int: return parseInt(data, 10) // case TYPE.float: return parseFloat(data) // case TYPE.bigint: return BigInt(data) // case TYPE.array: // case TYPE.object: // try { // return JSON.parse(data) // } catch { // return null // } // case TYPE.symbol: return Symbol.for(data) // case TYPE.undefined: return undefined // } // } // try { // return JSON.parse(value) // } catch { // return value // } // } // private toText(value: AcceptedValue): string { // if (value === null) // return `${TYPE.null}${this.separator}` // if (value === undefined) // return `${TYPE.undefined}${this.separator}` // const type = typeof value // if (type === 'boolean') // return `${TYPE.boolean}${this.separator}${value ? 'true' : 'false'}` // encurtar para 1/0 // if (type === 'string') // return `${TYPE.string}${this.separator}${value}` // if (type === 'number') // return `${Number.isInteger(value) ? TYPE.int : TYPE.float}${this.separator}${value}` // if (type === 'bigint') // return `${TYPE.bigint}${this.separator}${value?.toString()}` // if (type === 'symbol') // // @ts-ignore // return `${TYPE.symbol}${this.separator}${Symbol.keyFor(value) ?? value?.toString()}` // if (Array.isArray(value)) // return `${TYPE.array}${this.separator}${JSON.stringify(value)}` // if (type === 'object') // return `${TYPE.object}${this.separator}${JSON.stringify(value)}` // return '' // } // private cipher(str: string | null | undefined, key: string = ''): string { // if (!str || !key || !str.length) return '' // const result: string[] = new Array // let dataLength = str.length - 1 // const keyLength = key.length - 1 // do { // result[dataLength] = String.fromCharCode(str.charCodeAt(dataLength) ^ key.charCodeAt(dataLength % keyLength)) // // result.push(String.fromCharCode(str.charCodeAt(dataLength) ^ key.charCodeAt(dataLength % keyLength))) // } while (dataLength--) // return result.join('') // // return result.reverse().join('') // } // private maybeUseAlphabet(data: string, from?: string, to?: string): string { // if (!data || typeof data !== 'string' || !from || !to || from === to) // return data // return this.strtr(data, from, to) // } // private strtr(str: string, from: string, to: string): string { // let result = '' // for (let i = 0; i < str.length; i++) { // const char = str[i] // const index = from.indexOf(char) // result += index !== -1 && index < to.length ? to[index] : char // } // return result // } // private forgeKey(entropy: string = ''): string { // return sha256(this.config.key + entropy, 'base64url') // // return sha256(this.config.key + entropy, 'binary').toString('binary') // } // baseEncode(data: string | Buffer): string { // return this.maybeUseAlphabet( // UrlSafeBase64.encode(data), // this.config.baseAlphabet, // this.config.alphabet // ) // } // baseDecode(data: string): string { // return UrlSafeBase64.decode(this.maybeUseAlphabet( // data, // this.config.alphabet, // this.config.baseAlphabet // )) // } // }