'use strict';

var index_js = require('buffer/index.js');

var x=t=>(index_js.Buffer.isBuffer(t)?t:index_js.Buffer.from(t)).toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,""),j={encryption:{saltBits:256,algorithm:"aes-256-cbc",iterations:1,minPasswordlength:32},integrity:{saltBits:256,algorithm:"sha256",iterations:1,minPasswordlength:32},ttl:0,timestampSkewSec:60,localtimeOffsetMsec:0},v=t=>({...t,encryption:{...t.encryption},integrity:{...t.integrity}}),u={"aes-128-ctr":{keyBits:128,ivBits:128,name:"AES-CTR"},"aes-256-cbc":{keyBits:256,ivBits:128,name:"AES-CBC"},sha256:{keyBits:256,name:"SHA-256"}},A="2",K=`Fe26.${A}`,M=(t,n)=>{let e=index_js.Buffer.allocUnsafe(n);return t.getRandomValues(e),e},b=(t,n)=>{if(n<1)throw Error("Invalid random bits count");let e=Math.ceil(n/8);return M(t,e)},H=async(t,n,e,s,r,c)=>{let o=new TextEncoder,i=o.encode(n),a=await t.subtle.importKey("raw",i,"PBKDF2",!1,["deriveBits"]),f=o.encode(e),y={name:"PBKDF2",hash:c,salt:f,iterations:s},d=await t.subtle.deriveBits(y,a,r*8);return index_js.Buffer.from(d)},E=async(t,n,e)=>{var a;if(n==null||!n.length)throw new Error("Empty password");if(e==null||typeof e!="object")throw new Error("Bad options");if(!(e.algorithm in u))throw new Error(`Unknown algorithm: ${e.algorithm}`);let s=u[e.algorithm],r={},c=(a=e.hmac)!=null?a:!1,o=c?{name:"HMAC",hash:s.name}:{name:s.name},i=c?["sign","verify"]:["encrypt","decrypt"];if(typeof n=="string"){if(n.length<e.minPasswordlength)throw new Error(`Password string too short (min ${e.minPasswordlength} characters required)`);let{salt:f=""}=e;if(!f){let{saltBits:m=0}=e;if(!m)throw new Error("Missing salt and saltBits options");f=b(t,m).toString("hex");}let y=await H(t,n,f,e.iterations,s.keyBits/8,"SHA-1"),d=await t.subtle.importKey("raw",y,o,!1,i);r.key=d,r.salt=f;}else {if(n.length<s.keyBits/8)throw new Error("Key buffer (password) too small");r.key=await t.subtle.importKey("raw",n,o,!1,i),r.salt="";}return e.iv?r.iv=e.iv:"ivBits"in s&&(r.iv=b(t,s.ivBits)),r},I=async(t,n,e,s)=>{let r=await E(t,n,e),o=new TextEncoder().encode(s),i=await t.subtle.encrypt({name:u[e.algorithm].name,iv:r.iv},r.key,o);return {encrypted:index_js.Buffer.from(i),key:r}},R=async(t,n,e,s)=>{let r=await E(t,n,e),c=await t.subtle.decrypt({name:u[e.algorithm].name,iv:r.iv},r.key,index_js.Buffer.isBuffer(s)?s:index_js.Buffer.from(s));return new TextDecoder().decode(c)},k=async(t,n,e,s)=>{let r=await E(t,n,{...e,hmac:!0}),o=new TextEncoder().encode(s),i=await t.subtle.sign({name:"HMAC"},r.key,o);return {digest:x(index_js.Buffer.from(i)),salt:r.salt}},$=t=>typeof t=="object"&&!index_js.Buffer.isBuffer(t)?"secret"in t?{id:t.id,encryption:t.secret,integrity:t.secret}:{id:t.id,encryption:t.encryption,integrity:t.integrity}:{encryption:t,integrity:t},F=async(t,n,e,s)=>{if(!e)throw Error("Empty password");let r=v(s),c=Date.now()+(r.localtimeOffsetMsec||0),o=JSON.stringify(n),i=$(e),{id:a=""}=i;if(a&&!/^\w+$/.test(a))throw new Error("Invalid password id");let{encrypted:f,key:y}=await I(t,i.encryption,r.encryption,o),d=x(f),m=x(y.iv),w=r.ttl?c+r.ttl:"",g=`${K}*${a}*${y.salt}*${m}*${d}*${w}`,h=await k(t,i.integrity,r.integrity,g);return `${g}*${h.salt}*${h.digest}`},D=(t,n)=>{let e=t.length===n.length?0:1;e&&(n=t);for(let s=0;s<t.length;s+=1)e|=t.charCodeAt(s)^n.charCodeAt(s);return e===0},U=async(t,n,e,s)=>{if(!e)throw Error("Empty password");let r=v(s),c=Date.now()+(r.localtimeOffsetMsec||0),o=n.split("*");if(o.length!==8)throw new Error("Incorrect number of sealed components");let i=o[0],a=o[1],f=o[2],y=o[3],d=o[4],m=o[5],w=o[6],g=o[7],h=`${i}*${a}*${f}*${y}*${d}*${m}`;if(K!==i)throw new Error("Wrong mac prefix");if(m){if(!/^\d+$/.exec(m))throw new Error("Invalid expiration");if(parseInt(m,10)<=c-r.timestampSkewSec*1e3)throw new Error("Expired seal")}if(typeof e=="undefined"||typeof e=="string"&&e.length===0)throw new Error("Empty password");let p;if(typeof e=="object"&&!index_js.Buffer.isBuffer(e)){if(!((a||"default")in e))throw new Error(`Cannot find password: ${a}`);p=e[a||"default"];}else p=e;p=$(p);let P=r.integrity;P.salt=w;let O=await k(t,p.integrity,P,h);if(!D(O.digest,g))throw new Error("Bad hmac value");let C=index_js.Buffer.from(d,"base64"),B=r.encryption;B.salt=f,B.iv=index_js.Buffer.from(y,"base64");let S=await R(t,p.encryption,B,C);return S?JSON.parse(S):null};

Object.defineProperty(exports, 'Buffer', {
	enumerable: true,
	get: function () { return index_js.Buffer; }
});
exports.algorithms = u;
exports.base64urlEncode = x;
exports.clone = v;
exports.decrypt = R;
exports.defaults = j;
exports.encrypt = I;
exports.generateKey = E;
exports.hmacWithPassword = k;
exports.macFormatVersion = A;
exports.macPrefix = K;
exports.randomBits = b;
exports.seal = F;
exports.unseal = U;
