@tangle-network/sandbox 0.9.1-develop.20260624210934.e2730e8 → 0.9.2-develop.20260625093856.35d47c0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1,273 @@
1
- const a0_0x6ce4e6=a0_0x4a59;(function(_0x211c91,_0x4c3346){const _0x551e88=a0_0x4a59,_0x303c42=_0x211c91();while(!![]){try{const _0x46485f=-parseInt(_0x551e88(0xb9))/0x1+parseInt(_0x551e88(0xb4))/0x2+parseInt(_0x551e88(0xd3))/0x3+-parseInt(_0x551e88(0xb5))/0x4+-parseInt(_0x551e88(0xde))/0x5*(-parseInt(_0x551e88(0xc2))/0x6)+parseInt(_0x551e88(0xbb))/0x7*(parseInt(_0x551e88(0xeb))/0x8)+-parseInt(_0x551e88(0xf3))/0x9*(parseInt(_0x551e88(0xe8))/0xa);if(_0x46485f===_0x4c3346)break;else _0x303c42['push'](_0x303c42['shift']());}catch(_0x585ed6){_0x303c42['push'](_0x303c42['shift']());}}}(a0_0x1f55,0x907ca));import{createHmac,timingSafeEqual}from'\x6e\x6f\x64\x65\x3a\x63\x72\x79\x70\x74\x6f';function base64UrlEncode(_0x43c4c5){const _0x4414f7=a0_0x4a59;return(typeof _0x43c4c5===_0x4414f7(0xc0)?Buffer[_0x4414f7(0xcf)](_0x43c4c5):_0x43c4c5)['\x74\x6f\x53\x74\x72\x69\x6e\x67']('\x62\x61\x73\x65\x36\x34')['\x72\x65\x70\x6c\x61\x63\x65'](/\+/g,'\x2d')[_0x4414f7(0xea)](/\//g,'\x5f')['\x72\x65\x70\x6c\x61\x63\x65'](/=+$/,'');}function a0_0x1f55(){const _0x2778e4=['\x79\x77\x6e\x4a\x7a\x78\x6e\x5a','\x74\x32\x54\x31\x75\x4b\x69','\x77\x4b\x6e\x6d\x45\x67\x65','\x7a\x78\x48\x57','\x43\x32\x48\x48\x6d\x4a\x75\x32','\x43\x33\x72\x59\x41\x77\x35\x4e\x41\x77\x7a\x35','\x6e\x74\x62\x74\x42\x4c\x4c\x35\x44\x4c\x75','\x72\x77\x66\x6b\x44\x77\x53','\x43\x4d\x76\x57\x42\x67\x66\x4a\x7a\x71','\x6d\x4a\x43\x33\x6d\x64\x47\x34\x74\x30\x72\x6d\x79\x33\x72\x69','\x43\x32\x66\x55\x7a\x67\x6a\x56\x45\x65\x4c\x4b','\x74\x4e\x62\x34\x72\x4e\x47','\x43\x4d\x76\x48\x7a\x61','\x44\x65\x6e\x48\x71\x31\x4f','\x43\x32\x4c\x4e\x42\x4d\x4c\x55\x7a\x31\x6e\x4c\x79\x33\x6a\x4c\x44\x61','\x41\x75\x6a\x4d\x79\x31\x4b','\x7a\x67\x39\x4a\x44\x77\x31\x4c\x42\x4e\x72\x6a\x7a\x61','\x6d\x4a\x4b\x33\x6d\x64\x71\x59\x6d\x31\x50\x33\x44\x4b\x7a\x5a\x44\x47','\x44\x67\x4c\x4c\x43\x47','\x76\x66\x44\x67\x77\x65\x79','\x6e\x4a\x69\x33\x6d\x5a\x61\x59\x42\x67\x44\x4d\x77\x76\x76\x59','\x6d\x5a\x71\x32\x6e\x74\x43\x32\x41\x75\x4c\x64\x72\x77\x66\x69','\x71\x4d\x44\x56\x44\x4c\x65','\x42\x4d\x39\x33','\x7a\x4e\x6a\x4c\x7a\x71','\x6d\x4a\x6d\x31\x6d\x74\x6a\x6a\x43\x65\x72\x73\x74\x77\x6d','\x72\x65\x58\x58\x43\x65\x47','\x6d\x4a\x65\x33\x74\x66\x6e\x6e\x75\x77\x7a\x64','\x42\x67\x76\x55\x7a\x33\x72\x4f','\x7a\x4d\x58\x56\x42\x33\x69','\x43\x30\x76\x55\x43\x75\x4b','\x42\x77\x66\x34','\x43\x33\x72\x59\x41\x77\x35\x4e','\x71\x32\x35\x67\x72\x4c\x6d','\x6d\x5a\x71\x59\x6e\x4a\x62\x77\x75\x65\x4c\x53\x79\x75\x4b','\x41\x78\x6e\x5a\x44\x77\x76\x64\x42\x32\x58\x53\x79\x77\x6a\x56\x43\x4d\x66\x30\x41\x77\x39\x55','\x43\x67\x66\x59\x43\x32\x75','\x79\x32\x58\x56\x79\x32\x54\x74\x41\x32\x76\x33\x75\x32\x76\x4a\x42\x32\x35\x4b\x43\x57','\x75\x30\x35\x31\x75\x4e\x71','\x43\x68\x6a\x56\x7a\x68\x76\x4a\x44\x65\x4c\x4b','\x7a\x77\x35\x30\x7a\x78\x6a\x57\x43\x4d\x4c\x5a\x7a\x71','\x44\x67\x76\x5a\x44\x61','\x79\x32\x39\x53\x42\x67\x66\x49\x42\x33\x6a\x48\x44\x67\x4c\x56\x42\x47','\x44\x33\x62\x33\x7a\x32\x34','\x43\x68\x6a\x56\x41\x4d\x76\x4a\x44\x65\x4c\x4b','\x73\x4c\x44\x75','\x42\x77\x4c\x71\x41\x68\x61','\x7a\x4e\x6a\x56\x42\x71','\x44\x68\x72\x53\x74\x77\x4c\x55\x44\x78\x72\x4c\x43\x57','\x43\x4d\x76\x57\x7a\x77\x66\x30','\x42\x4e\x76\x54\x79\x4d\x76\x59','\x6d\x4a\x47\x33\x6e\x5a\x6d\x35\x6e\x4d\x6a\x4b\x79\x4b\x58\x76\x43\x47','\x7a\x67\x4c\x4e\x7a\x78\x6e\x30','\x77\x78\x44\x70\x71\x75\x43','\x72\x77\x72\x6c\x45\x78\x47','\x43\x67\x39\x57\x42\x77\x4b','\x43\x32\x76\x5a\x43\x32\x4c\x56\x42\x4b\x4c\x4b','\x43\x33\x62\x53\x41\x78\x71','\x79\x77\x58\x4e','\x44\x31\x44\x6f\x76\x4d\x4f','\x44\x67\x39\x74\x44\x68\x6a\x50\x42\x4d\x43','\x76\x4e\x72\x55\x7a\x77\x71','\x6e\x77\x39\x51\x44\x4d\x72\x58\x42\x47','\x74\x32\x7a\x33\x44\x67\x4f','\x79\x4d\x66\x5a\x7a\x74\x79\x30','\x72\x77\x50\x32\x42\x32\x43'];a0_0x1f55=function(){return _0x2778e4;};return a0_0x1f55();}function decodeBase64UrlToBuffer(_0x3678b0){const _0x4e3dfc=a0_0x4a59,_0x45f83e={'\x74\x43\x61\x43\x5a':function(_0x49b3a6,_0x3fce63){return _0x49b3a6+_0x3fce63;},'\x70\x6f\x70\x6d\x69':function(_0x58187c,_0x33096b){return _0x58187c%_0x33096b;},'\x59\x77\x4f\x41\x47':function(_0x24be6b,_0x362d8c){return _0x24be6b-_0x362d8c;}};if(!/^[A-Za-z0-9_-]*$/[_0x4e3dfc(0xc9)](_0x3678b0))return null;const _0x71435c=_0x45f83e[_0x4e3dfc(0xef)](_0x3678b0,'\x3d'['\x72\x65\x70\x65\x61\x74'](_0x45f83e[_0x4e3dfc(0xd7)](_0x45f83e[_0x4e3dfc(0xd5)](0x4,_0x45f83e[_0x4e3dfc(0xd7)](_0x3678b0[_0x4e3dfc(0xbc)],0x4)),0x4)));return Buffer[_0x4e3dfc(0xcf)](_0x71435c[_0x4e3dfc(0xea)](/-/g,'\x2b')['\x72\x65\x70\x6c\x61\x63\x65'](/_/g,'\x2f'),_0x4e3dfc(0xe0));}function createSignature(_0x531d3c,_0x5dda2d){const _0x174726=a0_0x4a59,_0x444b2d={'\x4f\x6b\x75\x52\x42':function(_0x40bd09,_0x384ea4){return _0x40bd09(_0x384ea4);},'\x5a\x43\x4c\x78\x61':function(_0x154933,_0x182b95,_0x3dcc9e){return _0x154933(_0x182b95,_0x3dcc9e);}};return _0x444b2d[_0x174726(0xe3)](base64UrlEncode,_0x444b2d[_0x174726(0xe4)](createHmac,_0x174726(0xe6),_0x5dda2d)['\x75\x70\x64\x61\x74\x65'](_0x531d3c)[_0x174726(0xd4)]());}const JWT_HEADER=base64UrlEncode(JSON['\x73\x74\x72\x69\x6e\x67\x69\x66\x79']({'\x61\x6c\x67':'\x48\x53\x32\x35\x36','\x74\x79\x70':a0_0x6ce4e6(0xcd)}));function issueToken(_0x1257e7,_0x2a4873,_0x461bf2){const _0x511611=a0_0x6ce4e6,_0xa71584={'\x4e\x70\x78\x46\x78':function(_0xa6e552,_0x39e0a2){return _0xa6e552/_0x39e0a2;},'\x54\x57\x46\x58\x46':function(_0x2a6232,_0x3a068c){return _0x2a6232*_0x3a068c;},'\x69\x42\x66\x63\x59':function(_0x321b42,_0x649cd5){return _0x321b42(_0x649cd5);}},_0x3b429a=Math[_0x511611(0xbd)](_0xa71584[_0x511611(0xed)](Date[_0x511611(0xb7)](),0x3e8)),_0x23955e={..._0x2a4873,'\x69\x61\x74':_0x3b429a,'\x65\x78\x70':_0x3b429a+_0xa71584[_0x511611(0xb3)](_0x461bf2,0x3c)},_0x2ed8b0=JWT_HEADER+'\x2e'+_0xa71584[_0x511611(0xf1)](base64UrlEncode,JSON[_0x511611(0xe7)](_0x23955e));return _0x2ed8b0+'\x2e'+createSignature(_0x2ed8b0,_0x1257e7);}function issueReadToken(_0x3357bb,_0x1500df,_0x56efea){const _0x434ef1=a0_0x6ce4e6,_0x24a31b={'\x77\x57\x4e\x56\x6a':function(_0x6f99a1,_0x228385,_0x3c1ef4,_0x337306){return _0x6f99a1(_0x228385,_0x3c1ef4,_0x337306);}};return _0x24a31b[_0x434ef1(0xdb)](issueToken,_0x3357bb,{..._0x1500df,'\x74\x79\x70':_0x434ef1(0xee)},_0x56efea);}function issueSessionScopedToken(_0x3463d2,_0x89fa02,_0x61a308){return issueReadToken(_0x3463d2,_0x89fa02,_0x61a308);}function issueProjectScopedToken(_0x3b5f10,_0x2896f4,_0x4e633d){return issueReadToken(_0x3b5f10,_0x2896f4,_0x4e633d);}function issueBatchScopedToken(_0x5ab6f1,_0x3ec55e,_0x500538){return issueReadToken(_0x5ab6f1,_0x3ec55e,_0x500538);}function issueCollaborationToken(_0x33cd18,_0x1888de,_0x46b2df){const _0x3917df=a0_0x6ce4e6;return issueToken(_0x33cd18,{'\x73\x75\x62':_0x1888de['\x75\x73\x65\x72\x49\x64'],'\x73\x69\x64':_0x1888de[_0x3917df(0xd8)],'\x70\x69\x64':_0x1888de['\x70\x72\x6f\x64\x75\x63\x74\x49\x64'],'\x63\x69\x64':_0x1888de[_0x3917df(0xec)],'\x74\x79\x70':_0x3917df(0xca),'\x70\x72\x6f\x6a\x65\x63\x74\x49\x64':_0x1888de[_0x3917df(0xcc)],'\x64\x6f\x63\x75\x6d\x65\x6e\x74\x49\x64':_0x1888de[_0x3917df(0xf2)],'\x61\x63\x63\x65\x73\x73':_0x1888de[_0x3917df(0xe2)]},_0x46b2df);}function unsafeDecodeToken(_0x486b85){const _0x543838=a0_0x6ce4e6,_0x3d2913={'\x53\x6d\x70\x44\x5a':function(_0xb178f8,_0x2f9ae0){return _0xb178f8%_0x2f9ae0;},'\x44\x4c\x71\x70\x48':function(_0x280d59,_0x381af2){return _0x280d59-_0x381af2;}};try{const _0x50c91a=_0x486b85[_0x543838(0xd9)]('\x2e');if(_0x50c91a[_0x543838(0xbc)]!==0x3)return null;const _0x977b45=_0x50c91a[0x1];if(_0x977b45===void 0x0)return null;const _0x4fd627=_0x977b45+'\x3d'[_0x543838(0xd1)](_0x3d2913['\x53\x6d\x70\x44\x5a'](_0x3d2913[_0x543838(0xba)](0x4,_0x977b45[_0x543838(0xbc)]%0x4),0x4)),_0x276486=Buffer[_0x543838(0xcf)](_0x4fd627[_0x543838(0xea)](/-/g,'\x2b')['\x72\x65\x70\x6c\x61\x63\x65'](/_/g,'\x2f'),_0x543838(0xe0))[_0x543838(0xdc)]();return JSON[_0x543838(0xc4)](_0x276486);}catch{return null;}}function a0_0x4a59(_0x4ee350,_0x54fe39){_0x4ee350=_0x4ee350-0xb3;const _0x1f5578=a0_0x1f55();let _0x4a5912=_0x1f5578[_0x4ee350];if(a0_0x4a59['\x69\x54\x56\x5a\x44\x70']===undefined){var _0x545eb3=function(_0x387308){const _0x54745a='\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x2b\x2f\x3d';let _0x4aec1f='',_0x5c8a64='';for(let _0x50826c=0x0,_0x5df677,_0x343faa,_0x1777ef=0x0;_0x343faa=_0x387308['\x63\x68\x61\x72\x41\x74'](_0x1777ef++);~_0x343faa&&(_0x5df677=_0x50826c%0x4?_0x5df677*0x40+_0x343faa:_0x343faa,_0x50826c++%0x4)?_0x4aec1f+=String['\x66\x72\x6f\x6d\x43\x68\x61\x72\x43\x6f\x64\x65'](0xff&_0x5df677>>(-0x2*_0x50826c&0x6)):0x0){_0x343faa=_0x54745a['\x69\x6e\x64\x65\x78\x4f\x66'](_0x343faa);}for(let _0x301db6=0x0,_0x4333a0=_0x4aec1f['\x6c\x65\x6e\x67\x74\x68'];_0x301db6<_0x4333a0;_0x301db6++){_0x5c8a64+='\x25'+('\x30\x30'+_0x4aec1f['\x63\x68\x61\x72\x43\x6f\x64\x65\x41\x74'](_0x301db6)['\x74\x6f\x53\x74\x72\x69\x6e\x67'](0x10))['\x73\x6c\x69\x63\x65'](-0x2);}return decodeURIComponent(_0x5c8a64);};a0_0x4a59['\x43\x48\x79\x49\x79\x49']=_0x545eb3,a0_0x4a59['\x69\x49\x74\x6a\x4d\x74']={},a0_0x4a59['\x69\x54\x56\x5a\x44\x70']=!![];}const _0xbecc9e=_0x1f5578[0x0],_0x47678d=_0x4ee350+_0xbecc9e,_0x42c6b9=a0_0x4a59['\x69\x49\x74\x6a\x4d\x74'][_0x47678d];return!_0x42c6b9?(_0x4a5912=a0_0x4a59['\x43\x48\x79\x49\x79\x49'](_0x4a5912),a0_0x4a59['\x69\x49\x74\x6a\x4d\x74'][_0x47678d]=_0x4a5912):_0x4a5912=_0x42c6b9,_0x4a5912;}function verifyToken(_0x29972c,_0x3bc018,_0x3de5ce={}){const _0x80c5f=a0_0x6ce4e6,_0x48e071={'\x77\x70\x77\x67\x6e':function(_0x50fe5f,_0x58eb7e){return _0x50fe5f!==_0x58eb7e;},'\x72\x59\x51\x6c\x4c':function(_0x2881bc,_0x3fd215){return _0x2881bc%_0x3fd215;},'\x79\x71\x68\x43\x4b':function(_0x23fc97,_0x4dad2f){return _0x23fc97-_0x4dad2f;},'\x76\x71\x6c\x41\x66':function(_0x52b8cd,_0xe9da01){return _0x52b8cd%_0xe9da01;},'\x42\x67\x6f\x76\x51':_0x80c5f(0xe0),'\x76\x47\x54\x69\x63':function(_0x4adc2a,_0x4c9d71){return _0x4adc2a!==_0x4c9d71;},'\x43\x6e\x69\x43\x74':function(_0x3945f4,_0x4c7372,_0x502d10){return _0x3945f4(_0x4c7372,_0x502d10);},'\x73\x45\x6e\x71\x49':function(_0x29b46a,_0x5e6309){return _0x29b46a(_0x5e6309);},'\x53\x4e\x75\x52\x74':function(_0x5f04b5,_0x1b4d69){return _0x5f04b5||_0x1b4d69;},'\x43\x6e\x46\x46\x53':function(_0x3687db,_0x2fa225){return _0x3687db/_0x2fa225;},'\x6d\x69\x50\x68\x70':_0x80c5f(0xd2),'\x45\x6a\x76\x6f\x67':function(_0x594bcd,_0x3bfc8d){return _0x594bcd+_0x3bfc8d;}};try{const _0x3e0555=_0x29972c[_0x80c5f(0xd9)]('\x2e');if(_0x48e071[_0x80c5f(0xcb)](_0x3e0555['\x6c\x65\x6e\x67\x74\x68'],0x3))return null;const [_0x52dfed,_0x30ab47,_0x265dcc]=_0x3e0555;if(!_0x52dfed||!_0x30ab47||!_0x265dcc)return null;let _0x25565c;try{const _0x15099d=_0x52dfed+'\x3d'[_0x80c5f(0xd1)](_0x48e071['\x72\x59\x51\x6c\x4c'](_0x48e071['\x79\x71\x68\x43\x4b'](0x4,_0x48e071['\x76\x71\x6c\x41\x66'](_0x52dfed[_0x80c5f(0xbc)],0x4)),0x4)),_0x27709a=Buffer[_0x80c5f(0xcf)](_0x15099d[_0x80c5f(0xea)](/-/g,'\x2b')[_0x80c5f(0xea)](/_/g,'\x2f'),_0x48e071[_0x80c5f(0xb6)])[_0x80c5f(0xdc)]();_0x25565c=JSON['\x70\x61\x72\x73\x65'](_0x27709a);}catch{return null;}if(_0x48e071['\x76\x47\x54\x69\x63'](_0x25565c[_0x80c5f(0xda)],'\x48\x53\x32\x35\x36'))return null;const _0x2e4ac5=_0x48e071['\x43\x6e\x69\x43\x74'](createSignature,_0x52dfed+'\x2e'+_0x30ab47,_0x3bc018),_0x3a04e9=_0x48e071[_0x80c5f(0xbe)](decodeBase64UrlToBuffer,_0x265dcc),_0x5064aa=decodeBase64UrlToBuffer(_0x2e4ac5);if(_0x48e071[_0x80c5f(0xc6)](!_0x3a04e9,!_0x5064aa))return null;if(_0x3a04e9[_0x80c5f(0xbc)]!==_0x5064aa['\x6c\x65\x6e\x67\x74\x68'])return null;if(!timingSafeEqual(_0x3a04e9,_0x5064aa))return null;const _0x1fa769=_0x48e071[_0x80c5f(0xbe)](unsafeDecodeToken,_0x29972c);if(!_0x1fa769)return null;const _0x46f5b1=Math[_0x80c5f(0xbd)](_0x48e071[_0x80c5f(0xc1)](Date[_0x80c5f(0xb7)](),0x3e8)),_0x4be0c1=Math[_0x80c5f(0xbf)](0x0,_0x3de5ce[_0x80c5f(0xc5)]??0x0);if(typeof _0x1fa769['\x65\x78\x70']!==_0x48e071[_0x80c5f(0xce)]||_0x48e071[_0x80c5f(0xe1)](_0x1fa769['\x65\x78\x70'],_0x4be0c1)<_0x46f5b1)return null;return _0x1fa769;}catch{return null;}}function getTokenTTL(_0x5f8577){const _0x4ba016=a0_0x6ce4e6,_0x31466b={'\x56\x74\x6e\x65\x64':function(_0x278b15,_0x5a7ea8){return _0x278b15-_0x5a7ea8;}},_0x56e3f7=Math['\x66\x6c\x6f\x6f\x72'](Date['\x6e\x6f\x77']()/0x3e8);return _0x31466b[_0x4ba016(0xdd)](_0x5f8577[_0x4ba016(0xe5)],_0x56e3f7);}function isTokenExpiringSoon(_0x43ad1e,_0x5983e6=0x3c){const _0x259d6a=a0_0x6ce4e6,_0x4c8916={'\x4f\x66\x77\x74\x6a':function(_0x4637a3,_0x46034c){return _0x4637a3(_0x46034c);}};return _0x4c8916[_0x259d6a(0xdf)](getTokenTTL,_0x43ad1e)<=_0x5983e6;}var ProductTokenIssuer=class{['\x70\x72\x6f\x64\x75\x63\x74\x49\x64'];[a0_0x6ce4e6(0xf0)];[a0_0x6ce4e6(0xd0)];constructor(_0x5be348){const _0x2c07a7=a0_0x6ce4e6;this[_0x2c07a7(0xc7)]=_0x5be348[_0x2c07a7(0xc7)],this[_0x2c07a7(0xf0)]=_0x5be348[_0x2c07a7(0xf0)],this[_0x2c07a7(0xd0)]={'\x66\x72\x65\x65':_0x5be348['\x74\x74\x6c\x4d\x69\x6e\x75\x74\x65\x73']?.[_0x2c07a7(0xb8)]??0xf,'\x70\x72\x6f':_0x5be348[_0x2c07a7(0xd0)]?.['\x70\x72\x6f']??0xf0,'\x65\x6e\x74\x65\x72\x70\x72\x69\x73\x65':_0x5be348[_0x2c07a7(0xd0)]?.[_0x2c07a7(0xc8)]??0x1e0};}['\x69\x73\x73\x75\x65'](_0xb4073a){const _0x565ed8=a0_0x6ce4e6,_0x136e9c={'\x58\x77\x65\x69\x5a':_0x565ed8(0xb8),'\x63\x6f\x56\x59\x51':function(_0x1770cf,_0x3bdb63){return _0x1770cf+_0x3bdb63;},'\x45\x61\x4a\x75\x6b':function(_0x2d63f0,_0x289aae){return _0x2d63f0*_0x289aae;}},_0x3d991c=_0xb4073a[_0x565ed8(0xf4)]??_0x136e9c['\x58\x77\x65\x69\x5a'],_0x40d0c0=this[_0x565ed8(0xd0)][_0x3d991c]??this['\x74\x74\x6c\x4d\x69\x6e\x75\x74\x65\x73']['\x66\x72\x65\x65'];return{'\x74\x6f\x6b\x65\x6e':issueReadToken(this[_0x565ed8(0xf0)],{'\x73\x75\x62':_0xb4073a['\x75\x73\x65\x72\x49\x64'],'\x73\x69\x64':_0xb4073a[_0x565ed8(0xd8)],'\x70\x69\x64':this[_0x565ed8(0xc7)],'\x63\x69\x64':_0xb4073a[_0x565ed8(0xec)]},_0x40d0c0),'\x65\x78\x70\x69\x72\x65\x73\x41\x74':_0x136e9c['\x63\x6f\x56\x59\x51'](Math[_0x565ed8(0xbd)](Date['\x6e\x6f\x77']()/0x3e8),_0x136e9c[_0x565ed8(0xe9)](_0x40d0c0,0x3c))};}[a0_0x6ce4e6(0xc3)](_0x5768ee){const _0x54f6da=a0_0x6ce4e6,_0x59ad9c={'\x45\x64\x4b\x79\x78':function(_0x1542d0,_0x3ae9c0){return _0x1542d0+_0x3ae9c0;}},_0x249ecc=_0x5768ee[_0x54f6da(0xf4)]??_0x54f6da(0xb8),_0x55395c=this[_0x54f6da(0xd0)][_0x249ecc]??this['\x74\x74\x6c\x4d\x69\x6e\x75\x74\x65\x73'][_0x54f6da(0xb8)];return{'\x74\x6f\x6b\x65\x6e':issueCollaborationToken(this[_0x54f6da(0xf0)],{'\x75\x73\x65\x72\x49\x64':_0x5768ee['\x75\x73\x65\x72\x49\x64'],'\x73\x65\x73\x73\x69\x6f\x6e\x49\x64':_0x5768ee[_0x54f6da(0xd8)],'\x70\x72\x6f\x64\x75\x63\x74\x49\x64':this['\x70\x72\x6f\x64\x75\x63\x74\x49\x64'],'\x70\x72\x6f\x6a\x65\x63\x74\x49\x64':_0x5768ee[_0x54f6da(0xcc)],'\x64\x6f\x63\x75\x6d\x65\x6e\x74\x49\x64':_0x5768ee['\x64\x6f\x63\x75\x6d\x65\x6e\x74\x49\x64'],'\x61\x63\x63\x65\x73\x73':_0x5768ee[_0x54f6da(0xe2)],'\x73\x61\x6e\x64\x62\x6f\x78\x49\x64':_0x5768ee[_0x54f6da(0xec)]},_0x55395c),'\x65\x78\x70\x69\x72\x65\x73\x41\x74':_0x59ad9c[_0x54f6da(0xd6)](Math[_0x54f6da(0xbd)](Date['\x6e\x6f\x77']()/0x3e8),_0x55395c*0x3c)};}['\x67\x65\x74\x54\x74\x6c\x4d\x69\x6e\x75\x74\x65\x73'](_0x383639=a0_0x6ce4e6(0xb8)){const _0x2393fb=a0_0x6ce4e6;return this[_0x2393fb(0xd0)][_0x383639]??this['\x74\x74\x6c\x4d\x69\x6e\x75\x74\x65\x73'][_0x2393fb(0xb8)];}};export{ProductTokenIssuer,getTokenTTL,isTokenExpiringSoon,issueBatchScopedToken,issueCollaborationToken,issueProjectScopedToken,issueReadToken,issueSessionScopedToken,unsafeDecodeToken,verifyToken};
1
+ import { createHmac, timingSafeEqual } from "node:crypto";
2
+ //#region src/auth/tokens.ts
3
+ /**
4
+ * JWT Token Utilities
5
+ *
6
+ * Token generation and verification using HMAC-SHA256. Server-only
7
+ * (uses Node.js `crypto`).
8
+ */
9
+ /**
10
+ * Base64URL encode (RFC 7515).
11
+ */
12
+ function base64UrlEncode(data) {
13
+ return (typeof data === "string" ? Buffer.from(data) : data).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
14
+ }
15
+ /**
16
+ * Base64URL decode (RFC 7515) to raw bytes. Returns `null` if the
17
+ * input contains characters outside the base64url alphabet.
18
+ */
19
+ function decodeBase64UrlToBuffer(input) {
20
+ if (!/^[A-Za-z0-9_-]*$/.test(input)) return null;
21
+ const padded = input + "=".repeat((4 - input.length % 4) % 4);
22
+ return Buffer.from(padded.replace(/-/g, "+").replace(/_/g, "/"), "base64");
23
+ }
24
+ /**
25
+ * Create HMAC-SHA256 signature.
26
+ */
27
+ function createSignature(data, secret) {
28
+ return base64UrlEncode(createHmac("sha256", secret).update(data).digest());
29
+ }
30
+ /**
31
+ * JWT header (always the same for our use case).
32
+ */
33
+ const JWT_HEADER = base64UrlEncode(JSON.stringify({
34
+ alg: "HS256",
35
+ typ: "JWT"
36
+ }));
37
+ function issueToken(signingSecret, payload, ttlMinutes) {
38
+ const now = Math.floor(Date.now() / 1e3);
39
+ const fullPayload = {
40
+ ...payload,
41
+ iat: now,
42
+ exp: now + ttlMinutes * 60
43
+ };
44
+ const data = `${JWT_HEADER}.${base64UrlEncode(JSON.stringify(fullPayload))}`;
45
+ return `${data}.${createSignature(data, signingSecret)}`;
46
+ }
47
+ /**
48
+ * Issue a read token (JWT) for WebSocket authentication.
49
+ *
50
+ * @param signingSecret - The product's signing secret
51
+ * @param payload - Token payload (without iat/exp/typ, those are added)
52
+ * @param ttlMinutes - Token TTL in minutes
53
+ */
54
+ function issueReadToken(signingSecret, payload, ttlMinutes) {
55
+ return issueToken(signingSecret, {
56
+ ...payload,
57
+ typ: "read"
58
+ }, ttlMinutes);
59
+ }
60
+ /**
61
+ * Issue a session-scoped token (JWT) for WebSocket authentication.
62
+ * Grants access to a single session's events.
63
+ */
64
+ function issueSessionScopedToken(signingSecret, payload, ttlMinutes) {
65
+ return issueReadToken(signingSecret, payload, ttlMinutes);
66
+ }
67
+ /**
68
+ * Issue a project-scoped token (JWT) for WebSocket authentication.
69
+ * Grants access to all sessions within a single project.
70
+ */
71
+ function issueProjectScopedToken(signingSecret, payload, ttlMinutes) {
72
+ return issueReadToken(signingSecret, payload, ttlMinutes);
73
+ }
74
+ /**
75
+ * Issue a batch-scoped token (JWT) for WebSocket authentication.
76
+ * Grants access to multiple projects (organization-level access).
77
+ */
78
+ function issueBatchScopedToken(signingSecret, payload, ttlMinutes) {
79
+ return issueReadToken(signingSecret, payload, ttlMinutes);
80
+ }
81
+ /**
82
+ * Issue a collaboration-scoped token (JWT) for collaborative document access.
83
+ * Grants read or write access to a single document in one project.
84
+ */
85
+ function issueCollaborationToken(signingSecret, payload, ttlMinutes) {
86
+ return issueToken(signingSecret, {
87
+ sub: payload.userId,
88
+ sid: payload.sessionId,
89
+ pid: payload.productId,
90
+ cid: payload.sandboxId,
91
+ typ: "collaboration",
92
+ projectId: payload.projectId,
93
+ documentId: payload.documentId,
94
+ access: payload.access
95
+ }, ttlMinutes);
96
+ }
97
+ /**
98
+ * Decode a JWT **without verifying its signature**.
99
+ *
100
+ * The deliberately scary name is the API contract: an HMAC-signed token
101
+ * whose signature has not been verified is a self-asserted blob of JSON,
102
+ * not an authenticated claim. Treating its fields as authoritative
103
+ * (e.g. `if (unsafeDecodeToken(t).sub === userId) grantAccess()`) is a
104
+ * straightforward authorization bypass — an attacker can mint any
105
+ * payload they like.
106
+ *
107
+ * Use this only when the signature has already been validated upstream
108
+ * (e.g. by an API gateway that strips the token after verification),
109
+ * for client-side `exp` peeking to decide whether to refresh, or for
110
+ * routing/logging keyed off non-security-sensitive claims.
111
+ *
112
+ * For any access-control decision, use {@link verifyToken} instead.
113
+ *
114
+ * Returns `null` if the token is malformed.
115
+ */
116
+ function unsafeDecodeToken(token) {
117
+ try {
118
+ const parts = token.split(".");
119
+ if (parts.length !== 3) return null;
120
+ const payload = parts[1];
121
+ if (payload === void 0) return null;
122
+ const padded = payload + "=".repeat((4 - payload.length % 4) % 4);
123
+ const decoded = Buffer.from(padded.replace(/-/g, "+").replace(/_/g, "/"), "base64").toString();
124
+ return JSON.parse(decoded);
125
+ } catch {
126
+ return null;
127
+ }
128
+ }
129
+ /**
130
+ * Verify a JWT's HMAC-SHA256 signature against `signingSecret` and
131
+ * check that it has not expired. Returns the decoded payload on
132
+ * success, or `null` on any failure (malformed token, bad signature,
133
+ * expired, or unexpected algorithm).
134
+ *
135
+ * Signature comparison is constant-time. Callers must use this — not
136
+ * {@link unsafeDecodeToken} — for any authorization decision.
137
+ *
138
+ * @param token - The JWT to verify
139
+ * @param signingSecret - The same secret used to issue the token
140
+ * @param options.clockSkewSeconds - Tolerance for `exp` checks; default `0`
141
+ */
142
+ function verifyToken(token, signingSecret, options = {}) {
143
+ try {
144
+ const parts = token.split(".");
145
+ if (parts.length !== 3) return null;
146
+ const [headerB64, payloadB64, signatureB64] = parts;
147
+ if (!headerB64 || !payloadB64 || !signatureB64) return null;
148
+ let header;
149
+ try {
150
+ const headerPadded = headerB64 + "=".repeat((4 - headerB64.length % 4) % 4);
151
+ const headerJson = Buffer.from(headerPadded.replace(/-/g, "+").replace(/_/g, "/"), "base64").toString();
152
+ header = JSON.parse(headerJson);
153
+ } catch {
154
+ return null;
155
+ }
156
+ if (header.alg !== "HS256") return null;
157
+ const expectedSig = createSignature(`${headerB64}.${payloadB64}`, signingSecret);
158
+ const providedRaw = decodeBase64UrlToBuffer(signatureB64);
159
+ const expectedRaw = decodeBase64UrlToBuffer(expectedSig);
160
+ if (!providedRaw || !expectedRaw) return null;
161
+ if (providedRaw.length !== expectedRaw.length) return null;
162
+ if (!timingSafeEqual(providedRaw, expectedRaw)) return null;
163
+ const payload = unsafeDecodeToken(token);
164
+ if (!payload) return null;
165
+ const now = Math.floor(Date.now() / 1e3);
166
+ const skew = Math.max(0, options.clockSkewSeconds ?? 0);
167
+ if (typeof payload.exp !== "number" || payload.exp + skew < now) return null;
168
+ return payload;
169
+ } catch {
170
+ return null;
171
+ }
172
+ }
173
+ /**
174
+ * Get time until token expires (in seconds).
175
+ * Returns negative if expired.
176
+ */
177
+ function getTokenTTL(payload) {
178
+ const now = Math.floor(Date.now() / 1e3);
179
+ return payload.exp - now;
180
+ }
181
+ /**
182
+ * Check if token is expiring soon (within buffer seconds).
183
+ */
184
+ function isTokenExpiringSoon(payload, bufferSeconds = 60) {
185
+ return getTokenTTL(payload) <= bufferSeconds;
186
+ }
187
+ //#endregion
188
+ //#region src/auth/index.ts
189
+ /**
190
+ * Authentication Utilities
191
+ *
192
+ * Token issuance for application backends. Server-only (uses Node.js crypto).
193
+ *
194
+ * @example
195
+ * ```typescript
196
+ * import { ProductTokenIssuer } from "@tangle-network/sandbox/auth";
197
+ *
198
+ * const issuer = new ProductTokenIssuer({
199
+ * productId: "my-product",
200
+ * signingSecret: process.env.SANDBOX_SIGNING_SECRET!,
201
+ * });
202
+ *
203
+ * const { token, expiresAt } = issuer.issue({
204
+ * userId: "user_123",
205
+ * sessionId: "sess_abc",
206
+ * tier: "pro",
207
+ * });
208
+ * ```
209
+ *
210
+ * @packageDocumentation
211
+ */
212
+ /**
213
+ * Token issuer for application backend services.
214
+ *
215
+ * Use this in your backend to issue read tokens for WebSocket connections.
216
+ */
217
+ var ProductTokenIssuer = class {
218
+ productId;
219
+ signingSecret;
220
+ ttlMinutes;
221
+ constructor(config) {
222
+ this.productId = config.productId;
223
+ this.signingSecret = config.signingSecret;
224
+ this.ttlMinutes = {
225
+ free: config.ttlMinutes?.free ?? 15,
226
+ pro: config.ttlMinutes?.pro ?? 240,
227
+ enterprise: config.ttlMinutes?.enterprise ?? 480
228
+ };
229
+ }
230
+ /**
231
+ * Issue a read token for a user session.
232
+ */
233
+ issue(params) {
234
+ const tier = params.tier ?? "free";
235
+ const ttl = this.ttlMinutes[tier] ?? this.ttlMinutes.free;
236
+ return {
237
+ token: issueReadToken(this.signingSecret, {
238
+ sub: params.userId,
239
+ sid: params.sessionId,
240
+ pid: this.productId,
241
+ cid: params.sandboxId
242
+ }, ttl),
243
+ expiresAt: Math.floor(Date.now() / 1e3) + ttl * 60
244
+ };
245
+ }
246
+ /**
247
+ * Issue a collaboration token for a single document.
248
+ */
249
+ issueCollaboration(params) {
250
+ const tier = params.tier ?? "free";
251
+ const ttl = this.ttlMinutes[tier] ?? this.ttlMinutes.free;
252
+ return {
253
+ token: issueCollaborationToken(this.signingSecret, {
254
+ userId: params.userId,
255
+ sessionId: params.sessionId,
256
+ productId: this.productId,
257
+ projectId: params.projectId,
258
+ documentId: params.documentId,
259
+ access: params.access,
260
+ sandboxId: params.sandboxId
261
+ }, ttl),
262
+ expiresAt: Math.floor(Date.now() / 1e3) + ttl * 60
263
+ };
264
+ }
265
+ /**
266
+ * Get the TTL in minutes for a tier.
267
+ */
268
+ getTtlMinutes(tier = "free") {
269
+ return this.ttlMinutes[tier] ?? this.ttlMinutes.free;
270
+ }
271
+ };
272
+ //#endregion
273
+ export { ProductTokenIssuer, getTokenTTL, isTokenExpiringSoon, issueBatchScopedToken, issueCollaborationToken, issueProjectScopedToken, issueReadToken, issueSessionScopedToken, unsafeDecodeToken, verifyToken };