UNPKG

nodemod

Version:

A collection of node modules for The Really Project

60 lines 2.31 kB
import { createHmac } from 'crypto'; export class SignaturError extends Error { type; constructor(type, message) { super(); this.name = 'SignaturError'; this.message = message; this.type = type; } toJSON() { return { error: { type: this.type, message: this.message, }, }; } } function urlSafeBase64(s) { return s.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''); } export function signSync(data, secret, options) { const { separator = '.' } = options || {}; if (null == data) { throw new TypeError(`Expected 'data' to be defined, but received '${JSON.stringify(data)}'`); } if ('string' !== typeof (secret) || !secret.length) { throw new TypeError(`Expected 'secret' to be defined, but received '${secret}'`); } const stringData = JSON.stringify({ data }); const encoded = Buffer.from(stringData, 'utf8').toString('base64'); const signature = createHmac('sha256', secret).update(stringData).digest('base64'); return urlSafeBase64(`${encoded}${separator}${signature}`); } export function unsignSync(signature, secret, options) { const { separator = '.' } = options || {}; if ('string' !== typeof (signature) || !signature.length) { throw new TypeError(`Expected 'signature' to be defined, but received '${signature}'`); } if ('string' !== typeof (secret) || !secret.length) { throw new TypeError(`Expected 'secret' to be defined, but received '${secret}'`); } const [hash, enc] = signature.split(separator, 2); const decoded = Buffer.from((hash + '==='.slice((hash.length + 3) % 4)) .replace(/-/g, '+') .replace(/_/g, '/'), 'base64') .toString('utf8'); const signedDecoded = urlSafeBase64(createHmac('sha256', secret).update(decoded).digest('base64')); if (enc !== signedDecoded) { throw new SignaturError('invalid_signature', 'Signature not match'); } return JSON.parse(decoded).data; } export async function sign(data, secret, options) { return signSync(data, secret, options); } export async function unsign(signature, secret, options) { return unsignSync(signature, secret, options); } //# sourceMappingURL=index.js.map