cripta
Version:
A layer of encryption a little too judicious
212 lines (171 loc) • 6.59 kB
text/typescript
// 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
// ))
// }
// }