@buoy-gg/license 7.0.41 → 7.0.43
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.
- package/lib/commonjs/DeviceRegistrationModal.js +1 -1
- package/lib/commonjs/LicenseManager.js +16 -16
- package/lib/commonjs/accountAccess.js +1 -1
- package/lib/commonjs/api.js +1 -1
- package/lib/commonjs/cacheSignature.js +15 -15
- package/lib/commonjs/config.js +16 -16
- package/lib/commonjs/freeToken.js +5 -5
- package/lib/commonjs/hooks.js +16 -16
- package/lib/commonjs/index.js +2 -2
- package/lib/commonjs/index.web.js +1 -1
- package/lib/commonjs/realNow.js +1 -0
- package/lib/commonjs/storage.js +1 -1
- package/lib/commonjs/tier.js +16 -16
- package/lib/commonjs/weekendPro.js +18 -18
- package/lib/module/DeviceRegistrationModal.js +1 -1
- package/lib/module/LicenseManager.js +15 -15
- package/lib/module/accountAccess.js +1 -1
- package/lib/module/api.js +1 -1
- package/lib/module/cacheSignature.js +15 -15
- package/lib/module/config.js +16 -16
- package/lib/module/device-info.web.js +1 -1
- package/lib/module/freeToken.js +5 -5
- package/lib/module/hooks.js +16 -16
- package/lib/module/index.js +17 -17
- package/lib/module/index.web.js +17 -17
- package/lib/module/realNow.js +1 -0
- package/lib/module/storage.js +1 -1
- package/lib/module/storage.web.js +1 -1
- package/lib/module/tier.js +16 -16
- package/lib/module/weekendPro.js +17 -17
- package/lib/typescript/commonjs/realNow.d.ts +11 -0
- package/lib/typescript/module/realNow.d.ts +11 -0
- package/lib/web/chunks/LicenseManager-7D2GGBCB.mjs +1 -0
- package/lib/web/chunks/chunk-ZSTLYSNF.mjs +68 -0
- package/lib/web/index.mjs +3 -7
- package/package.json +2 -5
- package/lib/typescript/commonjs/DeviceRegistrationModal.d.ts.map +0 -1
- package/lib/typescript/commonjs/LicenseManager.d.ts.map +0 -1
- package/lib/typescript/commonjs/accountAccess.d.ts.map +0 -1
- package/lib/typescript/commonjs/api.d.ts.map +0 -1
- package/lib/typescript/commonjs/cacheSignature.d.ts.map +0 -1
- package/lib/typescript/commonjs/config.d.ts.map +0 -1
- package/lib/typescript/commonjs/device-info.d.ts.map +0 -1
- package/lib/typescript/commonjs/device-info.web.d.ts.map +0 -1
- package/lib/typescript/commonjs/fingerprint.d.ts.map +0 -1
- package/lib/typescript/commonjs/fingerprint.web.d.ts.map +0 -1
- package/lib/typescript/commonjs/foreground.d.ts.map +0 -1
- package/lib/typescript/commonjs/foreground.web.d.ts.map +0 -1
- package/lib/typescript/commonjs/freeToken.d.ts.map +0 -1
- package/lib/typescript/commonjs/headless.d.ts.map +0 -1
- package/lib/typescript/commonjs/hooks.d.ts.map +0 -1
- package/lib/typescript/commonjs/index.d.ts.map +0 -1
- package/lib/typescript/commonjs/index.web.d.ts.map +0 -1
- package/lib/typescript/commonjs/storage.d.ts.map +0 -1
- package/lib/typescript/commonjs/storage.web.d.ts.map +0 -1
- package/lib/typescript/commonjs/tier.d.ts.map +0 -1
- package/lib/typescript/commonjs/types.d.ts.map +0 -1
- package/lib/typescript/commonjs/weekendPro.d.ts.map +0 -1
- package/lib/typescript/module/DeviceRegistrationModal.d.ts.map +0 -1
- package/lib/typescript/module/LicenseManager.d.ts.map +0 -1
- package/lib/typescript/module/accountAccess.d.ts.map +0 -1
- package/lib/typescript/module/api.d.ts.map +0 -1
- package/lib/typescript/module/cacheSignature.d.ts.map +0 -1
- package/lib/typescript/module/config.d.ts.map +0 -1
- package/lib/typescript/module/device-info.d.ts.map +0 -1
- package/lib/typescript/module/device-info.web.d.ts.map +0 -1
- package/lib/typescript/module/fingerprint.d.ts.map +0 -1
- package/lib/typescript/module/fingerprint.web.d.ts.map +0 -1
- package/lib/typescript/module/foreground.d.ts.map +0 -1
- package/lib/typescript/module/foreground.web.d.ts.map +0 -1
- package/lib/typescript/module/freeToken.d.ts.map +0 -1
- package/lib/typescript/module/headless.d.ts.map +0 -1
- package/lib/typescript/module/hooks.d.ts.map +0 -1
- package/lib/typescript/module/index.d.ts.map +0 -1
- package/lib/typescript/module/index.web.d.ts.map +0 -1
- package/lib/typescript/module/storage.d.ts.map +0 -1
- package/lib/typescript/module/storage.web.d.ts.map +0 -1
- package/lib/typescript/module/tier.d.ts.map +0 -1
- package/lib/typescript/module/types.d.ts.map +0 -1
- package/lib/typescript/module/weekendPro.d.ts.map +0 -1
- package/lib/web/chunks/LicenseManager-AEFCYYMQ.mjs +0 -7
- package/lib/web/chunks/LicenseManager-JHLFWSUD.mjs +0 -2
- package/lib/web/chunks/LicenseManager-VWEJJHBH.mjs +0 -7
- package/lib/web/chunks/chunk-GRUXDUJG.mjs +0 -74
- package/lib/web/chunks/chunk-OPWF6JR6.mjs +0 -1480
- package/lib/web/chunks/chunk-TVOTAEQX.mjs +0 -1483
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
"use strict";/*!
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
*/import{getLicenseStorage as f}from"./storage";import{KEYGEN_CONFIG as U,LICENSE_STORAGE_KEY as R,LICENSE_CACHE_DURATION as S,LICENSE_REVALIDATION_INTERVAL as H,LICENSE_LAUNCH_VALIDATION_TTL as Y,LICENSE_TRANSIENT_RETRY_DELAYS as B,LICENSE_RATE_LIMIT_DEFAULT_WAIT as q,LICENSE_QUOTA_COOLDOWN as M,LICENSE_VERDICT_CACHE_DURATION as X,LICENSE_FLEET_MACHINE_THRESHOLD as J,LICENSE_QUIET_VALIDATION_TTL as Q,LICENSE_HOLD_STORAGE_KEY as I,DEVICE_FINGERPRINT_STORAGE_KEY as C}from"./config.js";import{validateLicense as W,activateMachine as k,parseValidationResult as j,isFatalLicenseError as $,isTransientLicenseError as Z,isAcceptedValidation as ee,isRateLimited as te,backoffAfter as ie,machineCount as se}from"./api.js";import{generateUUID as w,getDeviceMetadata as F,getDefaultDeviceName as N,isDevBundle as O}from"./fingerprint";import{signCache as b,verifyCacheSignature as g}from"./cacheSignature.js";import{isBuoyToken as re,verifyFreeToken as ae}from"./freeToken.js";import{resolveTier as ne,isRecognizedAccount as ce}from"./tier.js";import{resolveAccountAccess as he}from"./accountAccess.js";import{subscribeForeground as oe}from"./foreground";async function u(l,e){let t;try{return await Promise.race([l,new Promise(i=>{t=setTimeout(()=>i(e),15e3)})])}finally{if(t)clearTimeout(t)}}function m(l){if(l.tier==="pro"||l.tier==="free")return l.tier;return l.isPro?"pro":"free"}class le{state={isInitialized:false,isValidating:false,isPro:false,tier:"free",tierSource:"none",licenseKey:null,error:null,errorKind:null,expiresAt:null};listeners=new Set;revalidationTimer=null;cachedLicense=null;fingerprintPromise=null;initPromise=null;generation=0;persistence=Promise.resolve();verifiedAt=null;expiryTimer=null;removeForegroundListener=null;retryTimer=null;retryAttempt=0;deviceRegistrationCallback=null;pendingRegistration=null;async initialize(){if(this.initPromise)return this.initPromise;if(this.state.isInitialized)return;this.initPromise=this._doInitialize();return this.initPromise}async _doInitialize(){if(this.state.isInitialized)return;const e=this.generation;try{const t=await u(this.loadCachedLicense(),null);if(e!==this.generation){this.state.isInitialized=true;this.emit({type:"initialized",isPro:this.state.isPro});this.startRevalidationTimer();return}if(t&&(this.configuredKey===void 0||t.licenseKey===this.configuredKey)){const i=g(t);this.cachedLicense=t;this.state.licenseKey=t.licenseKey;if(i&&this.isCacheValid(t))this.applyTier(m(t));else this.lock();this.state.expiresAt=t.expiresAt?new Date(t.expiresAt):null;if(i&&this.isCacheValid(t))this.setVerifiedAt(t.cachedAt);if(this.configuredKey===void 0&&t.licenseKey&&!(i&&this.isCacheValid(t)&&this.isCacheFresh(t))){this.validateInBackground(t.licenseKey)}}this.state.isInitialized=true;this.emit({type:"initialized",isPro:this.state.isPro});this.startRevalidationTimer()}catch(t){console.warn("[React Buoy] License initialization failed:",t);this.state.isInitialized=true;this.emit({type:"initialized",isPro:false})}}async configure(e){if(e===void 0){await this.initialize();return this.hasAccountAccess()}const t=e.trim().toUpperCase();const i=++this.generation;this.cancelRetry();this.configuredKey=t||null;if(this.state.licenseKey!==this.configuredKey)this.lock();this.state.licenseKey=this.configuredKey;this.state.isValidating=!!t;this.emit({type:"validating",isPro:this.isPro()});await this.initialize();if(i!==this.generation)return false;if(!t){await this.clearLicense();return false}return this.setLicenseKey(t)}async setLicenseKey(e,t){if(!e||e.trim().length===0){this.state.error="License key is required";this.state.errorKind="verdict";return false}const i=e.trim().toUpperCase();const s=++this.generation;this.cancelRetry();if(!t?.isRetry)this.retryAttempt=0;if(this.state.licenseKey!==i)this.lock();this.state.licenseKey=i;this.state.isValidating=true;this.state.error=null;this.state.errorKind=null;this.emit({type:"validating",isPro:this.isPro()});if(re(i))return this.admitToken(i,s);if(!this.cachedLicense){const a=await u(this.loadCachedLicense(),null);if(s!==this.generation)return false;if(a?.licenseKey===i){this.cachedLicense=a;if(g(a)&&this.isCacheValid(a)){this.applyTier(m(a));this.state.expiresAt=a.expiresAt?new Date(a.expiresAt):null;this.setVerifiedAt(a.cachedAt);this.emit({type:"validating",isPro:this.isPro()})}}}const r=this.cachedLicense;if(!t?.force&&r&&r.valid&&r.licenseKey===i&&r.fingerprint&&g(r)&&this.isCacheValid(r)&&this.isCacheFresh(r)){this.applyTier(m(r));this.state.licenseKey=i;this.state.isValidating=false;this.state.error=null;this.state.errorKind=null;this.state.expiresAt=r.expiresAt?new Date(r.expiresAt):null;this.setVerifiedAt(r.cachedAt);this.emit({type:"validated",isPro:this.state.isPro});return true}const c=await u(this.loadHold(),null);if(s!==this.generation)return false;const y=(c?.backoffUntil??0)-Date.now();if(y>0){return this.standDown(i,s,"License server is rate limited; retrying later.",y)}if(!t?.force&&c?.key===i&&c.verdictAt!==void 0&&Date.now()-c.verdictAt>=0&&Date.now()-c.verdictAt<X){this.lock();this.state.isValidating=false;this.state.error=c.detail||"License could not be verified";this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:this.state.error});return false}let n;try{n=await W(i)}catch(a){const o=a instanceof Error?a.message:"Validation failed";if(s!==this.generation)return false;if(Z(a)){if(te(a)){const d=Math.min(ie(a,M,q)*2**this.retryAttempt,M);this.retryAttempt+=1;await this.saveHold({...this.hold,backoffUntil:Date.now()+d});if(s!==this.generation)return false;return this.standDown(i,s,o,d)}this.state.isValidating=false;if(this.cachedLicense&&this.cachedLicense.licenseKey===i&&g(this.cachedLicense)&&this.isCacheValid(this.cachedLicense)){this.applyTier(m(this.cachedLicense));this.state.error=null;this.state.errorKind=null;this.state.expiresAt=this.cachedLicense.expiresAt?new Date(this.cachedLicense.expiresAt):null;this.setVerifiedAt(this.cachedLicense.cachedAt);if(!this.isPro())this.scheduleRetry(i);this.emit({type:"validated",isPro:this.state.isPro});return true}this.state.error=o;this.state.errorKind="transport";this.scheduleRetry(i);this.emit({type:"error",isPro:this.state.isPro,error:o});return false}this.state.isValidating=false;this.state.error=o;this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:o});return false}try{if(s!==this.generation)return false;const a=j(n);const o=n.data?.relationships?.product?.data?.id;if((!o||o===U.productId)&&a.code==="EXPIRED"&&(ce(n.data)||this.cachedLicense?.licenseKey===i&&g(this.cachedLicense)&&this.isCacheValid(this.cachedLicense))){const L=Date.now();const x=await this.saveCache({licenseKey:i,licenseId:n.data?.id??"",valid:true,isPro:false,tier:"free",expiresAt:null,cachedAt:L,lastValidatedAt:L,fingerprint:this.cachedLicense?.licenseKey===i?this.cachedLicense.fingerprint:void 0},s);if(s!==this.generation||!x)return false;this.cachedLicense=x;this.applyTier("free");this.state.isValidating=false;this.state.expiresAt=null;this.setVerifiedAt(L);this.emit({type:"validated",isPro:false});return true}if($(a.code)||!ee(n)){this.lock();this.state.isValidating=false;this.state.error=a.detail||"License could not be verified";this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:this.state.error});await this.clearCachedLicense();await this.saveHold({key:i,code:a.code,detail:this.state.error,verdictAt:Date.now()});return false}if(!n.data){this.lock();this.state.isValidating=false;this.state.error=a.detail||"License not found";this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:this.state.error});await this.clearCachedLicense();return false}const d=ne(n.data);const A=n.data.id;const E=Date.now();const D=se(n)>=J;const P=O();const G=P&&!D;const z=d==="free"&&(D||!P);let _=this.cachedLicense?.fingerprint;let p=this.cachedLicense?.deviceName;let V=false;if(!_){_=await u(this.getOrCreateDeviceFingerprint(),w());if(s!==this.generation)return false;p=N();V=G}let v=false;if(V){if(this.deviceRegistrationCallback){this.pendingRegistration={licenseId:A,licenseKey:i,fingerprint:_};this.deviceRegistrationCallback({fingerprint:_,defaultName:p});v=true}else{this.registerDeviceAsync(A,i,_,p)}}const T={licenseKey:i,licenseId:A,valid:true,isPro:d==="pro",tier:d,expiresAt:n.data.attributes.expiry??null,cachedAt:E,lastValidatedAt:E,fingerprint:v?void 0:_,deviceName:v?void 0:p,quiet:z||void 0};const K=await this.saveCache(T,s);if(s!==this.generation||!K)return false;this.cachedLicense=K;this.applyTier(d);this.state.isValidating=false;this.state.expiresAt=T.expiresAt?new Date(T.expiresAt):null;this.setVerifiedAt(E);if(this.hold)await this.saveHold(null);if(s!==this.generation)return false;this.retryAttempt=0;this.emit({type:"validated",isPro:this.state.isPro});return true}catch(a){const o=a instanceof Error?a.message:"Validation failed";if(s!==this.generation)return false;this.state.isValidating=false;this.state.error=o;this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:o});return false}}scheduleRetry(e){this.cancelRetry();const t=B[this.retryAttempt];if(t===void 0)return;this.retryAttempt+=1;const i=this.generation;this.retryTimer=setTimeout(()=>{this.retryTimer=null;if(i!==this.generation)return;if(this.state.isValidating)return;void this.setLicenseKey(e,{force:true,isRetry:true})},t);if(typeof __DEV__!=="undefined"&&__DEV__){global.__LICENSE_MANAGER_RETRY_TIMER__=this.retryTimer}}async admitToken(e,t){const i=ae(e);if(t!==this.generation)return false;if(!i){this.lock();this.state.isValidating=false;this.state.error="This key is not valid. Check that it was copied completely.";this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:this.state.error});await this.clearCachedLicense();return false}const s=Date.now();const r=this.cachedLicense?.fingerprint??await u(this.getOrCreateDeviceFingerprint(),w());if(t!==this.generation)return false;const c=await this.saveCache({licenseKey:e,licenseId:`token:${i.accountHash}`,valid:true,isPro:false,tier:"free",expiresAt:null,cachedAt:s,lastValidatedAt:s,fingerprint:r,deviceName:this.cachedLicense?.deviceName??N(),quiet:true},t);if(t!==this.generation||!c)return false;this.cachedLicense=c;this.applyTier("free");this.state.isValidating=false;this.state.expiresAt=null;this.setVerifiedAt(s);this.retryAttempt=0;this.emit({type:"validated",isPro:false});return true}standDown(e,t,i,s){if(t!==this.generation)return false;this.state.isValidating=false;const r=this.cachedLicense;if(r&&r.licenseKey===e&&g(r)&&this.isCacheValid(r)){this.applyTier(m(r));this.state.error=null;this.state.errorKind=null;this.state.expiresAt=r.expiresAt?new Date(r.expiresAt):null;this.setVerifiedAt(r.cachedAt);if(!this.isPro())this.scheduleRetryIn(e,s);this.emit({type:"validated",isPro:this.state.isPro});return true}this.state.error=i;this.state.errorKind="transport";this.scheduleRetryIn(e,s);this.emit({type:"error",isPro:this.state.isPro,error:i});return false}scheduleRetryIn(e,t){this.cancelRetry();const i=this.generation;this.retryTimer=setTimeout(()=>{this.retryTimer=null;if(i!==this.generation)return;if(this.state.isValidating)return;void this.setLicenseKey(e,{force:true,isRetry:true})},Math.max(1,Math.min(t,2147483647)));if(typeof __DEV__!=="undefined"&&__DEV__)h.__LICENSE_MANAGER_RETRY_TIMER__=this.retryTimer}cancelRetry(){if(this.retryTimer){clearTimeout(this.retryTimer);this.retryTimer=null}}async clearLicense(){this.generation+=1;this.cancelRetry();this.retryAttempt=0;this.configuredKey=null;this.state.licenseKey=null;this.lock();this.state.expiresAt=null;this.state.error=null;this.state.errorKind=null;this.cachedLicense=null;this.pendingRegistration=null;this.state.isValidating=false;this.emit({type:"deactivated",isPro:false});await this.clearCachedLicense();if(this.hold?.verdictAt!==void 0){await this.saveHold(this.hold.backoffUntil?{backoffUntil:this.hold.backoffUntil}:null)}}applyTier(e){this.state.tier=e;this.state.tierSource="key";this.state.isPro=e==="pro"}lock(){this.state.tier="free";this.state.tierSource="none";this.state.isPro=false;this.verifiedAt=null;if(this.expiryTimer)clearTimeout(this.expiryTimer);this.expiryTimer=null}getTier(){if(!this.hasAccountAccess())return"free";if(this.state.expiresAt&&Date.now()>=this.state.expiresAt.getTime())return"free";return this.state.tier}isPro(){return this.getTier()==="pro"}hasEntitlement(e){return this.isPro()}getState(){const e=this.getAccountAccess();const t=this.getTier();return{...this.state,tier:t,isPro:t==="pro",access:e}}getAccountAccess(){return he({initialized:this.state.isInitialized,validating:this.state.isValidating,key:this.state.licenseKey,tierSource:this.state.tierSource,verifiedAt:this.verifiedAt})}hasAccountAccess(){return this.getAccountAccess().status==="admitted"}setVerifiedAt(e){this.verifiedAt=e;if(this.expiryTimer)clearTimeout(this.expiryTimer);const t=e+S;const i=this.state.expiresAt?.getTime();const s=i&&i>Date.now()?Math.min(t,i):t;const r=s-Date.now();this.expiryTimer=setTimeout(()=>{this.expiryTimer=null;if(this.verifiedAt!==e)return;this.emit({type:"validated",isPro:this.isPro()});if(Date.now()<t)this.setVerifiedAt(e)},Math.max(1,Math.min(r,2147483647)));if(typeof __DEV__!=="undefined"&&__DEV__)h.__LICENSE_MANAGER_EXPIRY_TIMER__=this.expiryTimer}subscribe(e){this.listeners.add(e);return()=>this.listeners.delete(e)}onDeviceRegistrationNeeded(e){this.deviceRegistrationCallback=e;return()=>{this.deviceRegistrationCallback=null}}async completeDeviceRegistration(e){if(!this.pendingRegistration){console.warn("[Buoy] No pending device registration");return}const{licenseId:t,licenseKey:i,fingerprint:s}=this.pendingRegistration;const r=this.generation;const c=e.trim()||N();const y=F();try{await k(t,i,s,c,y)}catch(n){const a=n instanceof Error?n.message:String(n);if(a==="FINGERPRINT_TAKEN"||a==="MACHINE_LIMIT_EXCEEDED"){}else{console.warn("[Buoy] Device registration failed:",a);throw n}}if(r!==this.generation)return;if(this.cachedLicense?.licenseKey===i){const n=await this.saveCache({...this.cachedLicense,fingerprint:s,deviceName:c},r);if(r!==this.generation)return;if(n)this.cachedLicense=n}this.pendingRegistration=null}emit(e){const t=[...this.listeners];t.forEach(i=>{try{i(e)}catch(s){console.warn("[React Buoy] License listener error:",s)}})}isCacheValid(e){const t=Date.now();const i=t-e.cachedAt;if(!e.valid||!Number.isFinite(e.cachedAt)||i<0||i>=S){return false}return true}isCacheFresh(e){const t=this.isQuiet(e)?Q:Y;return Date.now()-(e.lastValidatedAt??0)<t}isQuiet(e){if(e.quiet!==void 0)return e.quiet;return m(e)==="free"&&!O()}async loadHold(){if(this.hold!==void 0)return this.hold;try{const e=await f();const t=await e.getItem(I);const i=t?JSON.parse(t):null;this.hold=i&&typeof i==="object"?i:null}catch{this.hold=null}return this.hold}async saveHold(e){this.hold=e;try{const t=await f();if(e)await t.setItem(I,JSON.stringify(e));else await t.removeItem(I)}catch{}}async persistCache(e){const t=b(e);const i=await f();await i.setItem(R,JSON.stringify(t));return t}saveCache(e,t){const i=this.persistence.catch(()=>{}).then(async()=>{if(t!==this.generation)return null;const s=await this.persistCache(e);return t===this.generation?s:null});this.persistence=i;return u(i,b(e))}async loadCachedLicense(){try{await this.persistence.catch(()=>{});const e=await f();const t=await e.getItem(R);if(!t)return null;const i=JSON.parse(t);return i}catch(e){console.warn("[Buoy] Error loading cached license:",e);return null}}getOrCreateDeviceFingerprint(){if(!this.fingerprintPromise){this.fingerprintPromise=(async()=>{const e=await f();const t=await e.getItem(C);if(t)return t;const i=this.cachedLicense?.fingerprint||w();await e.setItem(C,i);return i})()}return this.fingerprintPromise}async clearCachedLicense(){this.cachedLicense=null;const e=this.persistence.catch(()=>{}).then(async()=>{const t=await f();await t.removeItem(R)});this.persistence=e;await u(e.catch(()=>{}),void 0)}registerDeviceAsync(e,t,i,s){const r=F();k(e,t,i,s,r).catch(c=>{if(c.message!=="FINGERPRINT_TAKEN"&&c.message!=="MACHINE_LIMIT_EXCEEDED"){console.warn("[Buoy] Device registration failed (non-blocking):",c.message)}})}validateInBackground(e){void this.setLicenseKey(e,{force:true,isRetry:true})}refreshAccess(){this.emit({type:"validated",isPro:this.isPro()})}startRevalidationTimer(){if(!this.removeForegroundListener){this.removeForegroundListener=oe(()=>this.refreshAccess());if(typeof __DEV__!=="undefined"&&__DEV__)h.__LICENSE_MANAGER_FOREGROUND_OFF__=this.removeForegroundListener}if(this.revalidationTimer){clearInterval(this.revalidationTimer)}this.revalidationTimer=setInterval(()=>{if(!this.state.licenseKey||this.state.isValidating)return;const e=this.cachedLicense;if(e&&e.licenseKey===this.state.licenseKey&&this.isCacheFresh(e))return;this.validateInBackground(this.state.licenseKey)},H);if(typeof __DEV__!=="undefined"&&__DEV__){global.__LICENSE_MANAGER_TIMER__=this.revalidationTimer}}stopRevalidationTimer(){this.removeForegroundListener?.();this.removeForegroundListener=null;if(this.expiryTimer)clearTimeout(this.expiryTimer);this.expiryTimer=null;if(this.revalidationTimer){clearInterval(this.revalidationTimer);this.revalidationTimer=null}this.cancelRetry()}async forceReregister(){if(this.cachedLicense){this.cachedLicense.fingerprint=void 0;this.cachedLicense.deviceName=void 0}this.fingerprintPromise=null;await this.clearCachedLicense();try{const e=await f();await e.removeItem(C)}catch{}}}export const LicenseManager=new le;const h=globalThis;if(typeof __DEV__!=="undefined"&&__DEV__){h.__LICENSE_MANAGER_FOREGROUND_OFF__?.();h.__LICENSE_MANAGER_FOREGROUND_OFF__=void 0;if(h.__LICENSE_MANAGER_EXPIRY_TIMER__)clearTimeout(h.__LICENSE_MANAGER_EXPIRY_TIMER__);if(h.__LICENSE_MANAGER_TIMER__){clearInterval(h.__LICENSE_MANAGER_TIMER__)}if(h.__LICENSE_MANAGER_RETRY_TIMER__){clearTimeout(h.__LICENSE_MANAGER_RETRY_TIMER__);h.__LICENSE_MANAGER_RETRY_TIMER__=void 0}}
|
|
2
|
+
* PROPRIETARY — Buoy Pro license enforcement. NOT open source.
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
|
5
|
+
* (https://buoy.gg/terms), not an OSS license.
|
|
6
|
+
*
|
|
7
|
+
* This file is the technological measure that controls access to paid Buoy Pro
|
|
8
|
+
* features. Modifying, patching, aliasing, stubbing, or otherwise altering it
|
|
9
|
+
* so that Pro features unlock without a valid license is a breach of the EULA
|
|
10
|
+
* and, in the United States, circumvention of an access control under
|
|
11
|
+
* 17 U.S.C. § 1201 — which applies whether or not any code is copied.
|
|
12
|
+
*
|
|
13
|
+
* Pro is $9/mo, and is free every weekend for anyone holding a key —
|
|
14
|
+
* including a free one (`npx buoy login`). Buy a key at
|
|
15
|
+
* https://buoy.gg or use it free on Saturday and Sunday.
|
|
16
|
+
*/import{getLicenseStorage as u}from"./storage";import{KEYGEN_CONFIG as H,LICENSE_STORAGE_KEY as R,LICENSE_CACHE_DURATION as M,LICENSE_REVALIDATION_INTERVAL as Y,LICENSE_LAUNCH_VALIDATION_TTL as B,LICENSE_TRANSIENT_RETRY_DELAYS as X,LICENSE_RATE_LIMIT_DEFAULT_WAIT as q,LICENSE_QUOTA_COOLDOWN as k,LICENSE_VERDICT_CACHE_DURATION as J,LICENSE_FLEET_MACHINE_THRESHOLD as Q,LICENSE_QUIET_VALIDATION_TTL as W,LICENSE_HOLD_STORAGE_KEY as C,DEVICE_FINGERPRINT_STORAGE_KEY as N}from"./config.js";import{validateLicense as j,activateMachine as F,parseValidationResult as $,isFatalLicenseError as Z,isTransientLicenseError as ee,isAcceptedValidation as te,isRateLimited as ie,backoffAfter as se,machineCount as re}from"./api.js";import{generateUUID as P,getDeviceMetadata as O,getDefaultDeviceName as V,isDevBundle as G}from"./fingerprint";import{signCache as b,verifyCacheSignature as p}from"./cacheSignature.js";import{isBuoyToken as ae,verifyFreeToken as ne}from"./freeToken.js";import{resolveTier as ce,isRecognizedAccount as he}from"./tier.js";import{resolveAccountAccess as oe}from"./accountAccess.js";import{subscribeForeground as le}from"./foreground";import{realNow as h}from"./realNow.js";async function _(d,e){let t;try{return await Promise.race([d,new Promise(i=>{t=setTimeout(()=>i(e),15e3)})])}finally{if(t)clearTimeout(t)}}function m(d){if(d.tier==="pro"||d.tier==="free")return d.tier;return d.isPro?"pro":"free"}class de{state={isInitialized:false,isValidating:false,isPro:false,tier:"free",tierSource:"none",licenseKey:null,error:null,errorKind:null,expiresAt:null};listeners=new Set;revalidationTimer=null;cachedLicense=null;fingerprintPromise=null;initPromise=null;generation=0;persistence=Promise.resolve();verifiedAt=null;expiryTimer=null;removeForegroundListener=null;retryTimer=null;retryAttempt=0;deviceRegistrationCallback=null;pendingRegistration=null;async initialize(){if(this.initPromise)return this.initPromise;if(this.state.isInitialized)return;this.initPromise=this._doInitialize();return this.initPromise}async _doInitialize(){if(this.state.isInitialized)return;const e=this.generation;try{const t=await _(this.loadCachedLicense(),null);if(e!==this.generation){this.state.isInitialized=true;this.emit({type:"initialized",isPro:this.state.isPro});this.startRevalidationTimer();return}if(t&&(this.configuredKey===void 0||t.licenseKey===this.configuredKey)){const i=p(t);this.cachedLicense=t;this.state.licenseKey=t.licenseKey;if(i&&this.isCacheValid(t))this.applyTier(m(t));else this.lock();this.state.expiresAt=t.expiresAt?new Date(t.expiresAt):null;if(i&&this.isCacheValid(t))this.setVerifiedAt(t.cachedAt);if(this.configuredKey===void 0&&t.licenseKey&&!(i&&this.isCacheValid(t)&&this.isCacheFresh(t))){this.validateInBackground(t.licenseKey)}}this.state.isInitialized=true;this.emit({type:"initialized",isPro:this.state.isPro});this.startRevalidationTimer()}catch(t){console.warn("[React Buoy] License initialization failed:",t);this.state.isInitialized=true;this.emit({type:"initialized",isPro:false})}}async configure(e){if(e===void 0){await this.initialize();return this.hasAccountAccess()}const t=e.trim().toUpperCase();const i=++this.generation;this.cancelRetry();this.configuredKey=t||null;if(this.state.licenseKey!==this.configuredKey)this.lock();this.state.licenseKey=this.configuredKey;this.state.isValidating=!!t;this.emit({type:"validating",isPro:this.isPro()});await this.initialize();if(i!==this.generation)return false;if(!t){await this.clearLicense();return false}return this.setLicenseKey(t)}async setLicenseKey(e,t){if(!e||e.trim().length===0){this.state.error="License key is required";this.state.errorKind="verdict";return false}const i=e.trim().toUpperCase();const s=++this.generation;this.cancelRetry();if(!t?.isRetry)this.retryAttempt=0;if(this.state.licenseKey!==i)this.lock();this.state.licenseKey=i;this.state.isValidating=true;this.state.error=null;this.state.errorKind=null;this.emit({type:"validating",isPro:this.isPro()});if(ae(i))return this.admitToken(i,s);if(!this.cachedLicense){const a=await _(this.loadCachedLicense(),null);if(s!==this.generation)return false;if(a?.licenseKey===i){this.cachedLicense=a;if(p(a)&&this.isCacheValid(a)){this.applyTier(m(a));this.state.expiresAt=a.expiresAt?new Date(a.expiresAt):null;this.setVerifiedAt(a.cachedAt);this.emit({type:"validating",isPro:this.isPro()})}}}const r=this.cachedLicense;if(!t?.force&&r&&r.valid&&r.licenseKey===i&&r.fingerprint&&p(r)&&this.isCacheValid(r)&&this.isCacheFresh(r)){this.applyTier(m(r));this.state.licenseKey=i;this.state.isValidating=false;this.state.error=null;this.state.errorKind=null;this.state.expiresAt=r.expiresAt?new Date(r.expiresAt):null;this.setVerifiedAt(r.cachedAt);this.emit({type:"validated",isPro:this.state.isPro});return true}const c=await _(this.loadHold(),null);if(s!==this.generation)return false;const g=(c?.backoffUntil??0)-h();if(g>0){return this.standDown(i,s,"License server is rate limited; retrying later.",g)}if(!t?.force&&c?.key===i&&c.verdictAt!==void 0&&h()-c.verdictAt>=0&&h()-c.verdictAt<J){this.lock();this.state.isValidating=false;this.state.error=c.detail||"License could not be verified";this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:this.state.error});return false}let n;try{n=await j(i)}catch(a){const l=a instanceof Error?a.message:"Validation failed";if(s!==this.generation)return false;if(ee(a)){if(ie(a)){const f=Math.min(se(a,k,q)*2**this.retryAttempt,k);this.retryAttempt+=1;await this.saveHold({...this.hold,backoffUntil:h()+f});if(s!==this.generation)return false;return this.standDown(i,s,l,f)}this.state.isValidating=false;if(this.cachedLicense&&this.cachedLicense.licenseKey===i&&p(this.cachedLicense)&&this.isCacheValid(this.cachedLicense)){this.applyTier(m(this.cachedLicense));this.state.error=null;this.state.errorKind=null;this.state.expiresAt=this.cachedLicense.expiresAt?new Date(this.cachedLicense.expiresAt):null;this.setVerifiedAt(this.cachedLicense.cachedAt);if(!this.isPro())this.scheduleRetry(i);this.emit({type:"validated",isPro:this.state.isPro});return true}this.state.error=l;this.state.errorKind="transport";this.scheduleRetry(i);this.emit({type:"error",isPro:this.state.isPro,error:l});return false}this.state.isValidating=false;this.state.error=l;this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:l});return false}try{if(s!==this.generation)return false;const a=$(n);const l=n.data?.relationships?.product?.data?.id;if((!l||l===H.productId)&&a.code==="EXPIRED"&&(he(n.data)||this.cachedLicense?.licenseKey===i&&p(this.cachedLicense)&&this.isCacheValid(this.cachedLicense))){const I=h();const x=await this.saveCache({licenseKey:i,licenseId:n.data?.id??"",valid:true,isPro:false,tier:"free",expiresAt:null,cachedAt:I,lastValidatedAt:I,fingerprint:this.cachedLicense?.licenseKey===i?this.cachedLicense.fingerprint:void 0},s);if(s!==this.generation||!x)return false;this.cachedLicense=x;this.applyTier("free");this.state.isValidating=false;this.state.expiresAt=null;this.setVerifiedAt(I);this.emit({type:"validated",isPro:false});return true}if(Z(a.code)||!te(n)){this.lock();this.state.isValidating=false;this.state.error=a.detail||"License could not be verified";this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:this.state.error});await this.clearCachedLicense();await this.saveHold({key:i,code:a.code,detail:this.state.error,verdictAt:h()});return false}if(!n.data){this.lock();this.state.isValidating=false;this.state.error=a.detail||"License not found";this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:this.state.error});await this.clearCachedLicense();return false}const f=ce(n.data);const A=n.data.id;const v=h();const w=re(n)>=Q;const K=G();const z=K&&!w;const U=f==="free"&&(w||!K);let y=this.cachedLicense?.fingerprint;let E=this.cachedLicense?.deviceName;let D=false;if(!y){y=await _(this.getOrCreateDeviceFingerprint(),P());if(s!==this.generation)return false;E=V();D=z}let T=false;if(D){if(this.deviceRegistrationCallback){this.pendingRegistration={licenseId:A,licenseKey:i,fingerprint:y};this.deviceRegistrationCallback({fingerprint:y,defaultName:E});T=true}else{this.registerDeviceAsync(A,i,y,E)}}const L={licenseKey:i,licenseId:A,valid:true,isPro:f==="pro",tier:f,expiresAt:n.data.attributes.expiry??null,cachedAt:v,lastValidatedAt:v,fingerprint:T?void 0:y,deviceName:T?void 0:E,quiet:U||void 0};const S=await this.saveCache(L,s);if(s!==this.generation||!S)return false;this.cachedLicense=S;this.applyTier(f);this.state.isValidating=false;this.state.expiresAt=L.expiresAt?new Date(L.expiresAt):null;this.setVerifiedAt(v);if(this.hold)await this.saveHold(null);if(s!==this.generation)return false;this.retryAttempt=0;this.emit({type:"validated",isPro:this.state.isPro});return true}catch(a){const l=a instanceof Error?a.message:"Validation failed";if(s!==this.generation)return false;this.state.isValidating=false;this.state.error=l;this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:l});return false}}scheduleRetry(e){this.cancelRetry();const t=X[this.retryAttempt];if(t===void 0)return;this.retryAttempt+=1;const i=this.generation;this.retryTimer=setTimeout(()=>{this.retryTimer=null;if(i!==this.generation)return;if(this.state.isValidating)return;void this.setLicenseKey(e,{force:true,isRetry:true})},t);if(typeof __DEV__!=="undefined"&&__DEV__){global.__LICENSE_MANAGER_RETRY_TIMER__=this.retryTimer}}async admitToken(e,t){const i=ne(e);if(t!==this.generation)return false;if(!i){this.lock();this.state.isValidating=false;this.state.error="This key is not valid. Check that it was copied completely.";this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:this.state.error});await this.clearCachedLicense();return false}const s=h();const r=this.cachedLicense?.fingerprint??await _(this.getOrCreateDeviceFingerprint(),P());if(t!==this.generation)return false;const c=await this.saveCache({licenseKey:e,licenseId:`token:${i.accountHash}`,valid:true,isPro:false,tier:"free",expiresAt:null,cachedAt:s,lastValidatedAt:s,fingerprint:r,deviceName:this.cachedLicense?.deviceName??V(),quiet:true},t);if(t!==this.generation||!c)return false;this.cachedLicense=c;this.applyTier("free");this.state.isValidating=false;this.state.expiresAt=null;this.setVerifiedAt(s);this.retryAttempt=0;this.emit({type:"validated",isPro:false});return true}standDown(e,t,i,s){if(t!==this.generation)return false;this.state.isValidating=false;const r=this.cachedLicense;if(r&&r.licenseKey===e&&p(r)&&this.isCacheValid(r)){this.applyTier(m(r));this.state.error=null;this.state.errorKind=null;this.state.expiresAt=r.expiresAt?new Date(r.expiresAt):null;this.setVerifiedAt(r.cachedAt);if(!this.isPro())this.scheduleRetryIn(e,s);this.emit({type:"validated",isPro:this.state.isPro});return true}this.state.error=i;this.state.errorKind="transport";this.scheduleRetryIn(e,s);this.emit({type:"error",isPro:this.state.isPro,error:i});return false}scheduleRetryIn(e,t){this.cancelRetry();const i=this.generation;this.retryTimer=setTimeout(()=>{this.retryTimer=null;if(i!==this.generation)return;if(this.state.isValidating)return;void this.setLicenseKey(e,{force:true,isRetry:true})},Math.max(1,Math.min(t,2147483647)));if(typeof __DEV__!=="undefined"&&__DEV__)o.__LICENSE_MANAGER_RETRY_TIMER__=this.retryTimer}cancelRetry(){if(this.retryTimer){clearTimeout(this.retryTimer);this.retryTimer=null}}async clearLicense(){this.generation+=1;this.cancelRetry();this.retryAttempt=0;this.configuredKey=null;this.state.licenseKey=null;this.lock();this.state.expiresAt=null;this.state.error=null;this.state.errorKind=null;this.cachedLicense=null;this.pendingRegistration=null;this.state.isValidating=false;this.emit({type:"deactivated",isPro:false});await this.clearCachedLicense();if(this.hold?.verdictAt!==void 0){await this.saveHold(this.hold.backoffUntil?{backoffUntil:this.hold.backoffUntil}:null)}}applyTier(e){this.state.tier=e;this.state.tierSource="key";this.state.isPro=e==="pro"}lock(){this.state.tier="free";this.state.tierSource="none";this.state.isPro=false;this.verifiedAt=null;if(this.expiryTimer)clearTimeout(this.expiryTimer);this.expiryTimer=null}getTier(){if(!this.hasAccountAccess())return"free";if(this.state.expiresAt&&h()>=this.state.expiresAt.getTime())return"free";return this.state.tier}isPro(){return this.getTier()==="pro"}hasEntitlement(e){return this.isPro()}getState(){const e=this.getAccountAccess();const t=this.getTier();return{...this.state,tier:t,isPro:t==="pro",access:e}}getAccountAccess(){return oe({initialized:this.state.isInitialized,validating:this.state.isValidating,key:this.state.licenseKey,tierSource:this.state.tierSource,verifiedAt:this.verifiedAt})}hasAccountAccess(){return this.getAccountAccess().status==="admitted"}setVerifiedAt(e){this.verifiedAt=e;if(this.expiryTimer)clearTimeout(this.expiryTimer);const t=e+M;const i=this.state.expiresAt?.getTime();const s=i&&i>h()?Math.min(t,i):t;const r=s-h();this.expiryTimer=setTimeout(()=>{this.expiryTimer=null;if(this.verifiedAt!==e)return;this.emit({type:"validated",isPro:this.isPro()});if(h()<t)this.setVerifiedAt(e)},Math.max(1,Math.min(r,2147483647)));if(typeof __DEV__!=="undefined"&&__DEV__)o.__LICENSE_MANAGER_EXPIRY_TIMER__=this.expiryTimer}subscribe(e){this.listeners.add(e);return()=>this.listeners.delete(e)}onDeviceRegistrationNeeded(e){this.deviceRegistrationCallback=e;return()=>{this.deviceRegistrationCallback=null}}async completeDeviceRegistration(e){if(!this.pendingRegistration){console.warn("[Buoy] No pending device registration");return}const{licenseId:t,licenseKey:i,fingerprint:s}=this.pendingRegistration;const r=this.generation;const c=e.trim()||V();const g=O();try{await F(t,i,s,c,g)}catch(n){const a=n instanceof Error?n.message:String(n);if(a==="FINGERPRINT_TAKEN"||a==="MACHINE_LIMIT_EXCEEDED"){}else{console.warn("[Buoy] Device registration failed:",a);throw n}}if(r!==this.generation)return;if(this.cachedLicense?.licenseKey===i){const n=await this.saveCache({...this.cachedLicense,fingerprint:s,deviceName:c},r);if(r!==this.generation)return;if(n)this.cachedLicense=n}this.pendingRegistration=null}emit(e){const t=[...this.listeners];t.forEach(i=>{try{i(e)}catch(s){console.warn("[React Buoy] License listener error:",s)}})}isCacheValid(e){const t=h();const i=t-e.cachedAt;if(!e.valid||!Number.isFinite(e.cachedAt)||i<0||i>=M){return false}return true}isCacheFresh(e){const t=this.isQuiet(e)?W:B;return h()-(e.lastValidatedAt??0)<t}isQuiet(e){if(e.quiet!==void 0)return e.quiet;return m(e)==="free"&&!G()}async loadHold(){if(this.hold!==void 0)return this.hold;try{const e=await u();const t=await e.getItem(C);const i=t?JSON.parse(t):null;this.hold=i&&typeof i==="object"?i:null}catch{this.hold=null}return this.hold}async saveHold(e){this.hold=e;try{const t=await u();if(e)await t.setItem(C,JSON.stringify(e));else await t.removeItem(C)}catch{}}async persistCache(e){const t=b(e);const i=await u();await i.setItem(R,JSON.stringify(t));return t}saveCache(e,t){const i=this.persistence.catch(()=>{}).then(async()=>{if(t!==this.generation)return null;const s=await this.persistCache(e);return t===this.generation?s:null});this.persistence=i;return _(i,b(e))}async loadCachedLicense(){try{await this.persistence.catch(()=>{});const e=await u();const t=await e.getItem(R);if(!t)return null;const i=JSON.parse(t);return i}catch(e){console.warn("[Buoy] Error loading cached license:",e);return null}}getOrCreateDeviceFingerprint(){if(!this.fingerprintPromise){this.fingerprintPromise=(async()=>{const e=await u();const t=await e.getItem(N);if(t)return t;const i=this.cachedLicense?.fingerprint||P();await e.setItem(N,i);return i})()}return this.fingerprintPromise}async clearCachedLicense(){this.cachedLicense=null;const e=this.persistence.catch(()=>{}).then(async()=>{const t=await u();await t.removeItem(R)});this.persistence=e;await _(e.catch(()=>{}),void 0)}registerDeviceAsync(e,t,i,s){const r=O();F(e,t,i,s,r).catch(c=>{if(c.message!=="FINGERPRINT_TAKEN"&&c.message!=="MACHINE_LIMIT_EXCEEDED"){console.warn("[Buoy] Device registration failed (non-blocking):",c.message)}})}validateInBackground(e){void this.setLicenseKey(e,{force:true,isRetry:true})}refreshAccess(){this.emit({type:"validated",isPro:this.isPro()})}startRevalidationTimer(){if(!this.removeForegroundListener){this.removeForegroundListener=le(()=>this.refreshAccess());if(typeof __DEV__!=="undefined"&&__DEV__)o.__LICENSE_MANAGER_FOREGROUND_OFF__=this.removeForegroundListener}if(this.revalidationTimer){clearInterval(this.revalidationTimer)}this.revalidationTimer=setInterval(()=>{if(!this.state.licenseKey||this.state.isValidating)return;const e=this.cachedLicense;if(e&&e.licenseKey===this.state.licenseKey&&this.isCacheFresh(e))return;this.validateInBackground(this.state.licenseKey)},Y);if(typeof __DEV__!=="undefined"&&__DEV__){global.__LICENSE_MANAGER_TIMER__=this.revalidationTimer}}stopRevalidationTimer(){this.removeForegroundListener?.();this.removeForegroundListener=null;if(this.expiryTimer)clearTimeout(this.expiryTimer);this.expiryTimer=null;if(this.revalidationTimer){clearInterval(this.revalidationTimer);this.revalidationTimer=null}this.cancelRetry()}async forceReregister(){if(this.cachedLicense){this.cachedLicense.fingerprint=void 0;this.cachedLicense.deviceName=void 0}this.fingerprintPromise=null;await this.clearCachedLicense();try{const e=await u();await e.removeItem(N)}catch{}}}export const LicenseManager=new de;const o=globalThis;if(typeof __DEV__!=="undefined"&&__DEV__){o.__LICENSE_MANAGER_FOREGROUND_OFF__?.();o.__LICENSE_MANAGER_FOREGROUND_OFF__=void 0;if(o.__LICENSE_MANAGER_EXPIRY_TIMER__)clearTimeout(o.__LICENSE_MANAGER_EXPIRY_TIMER__);if(o.__LICENSE_MANAGER_TIMER__){clearInterval(o.__LICENSE_MANAGER_TIMER__)}if(o.__LICENSE_MANAGER_RETRY_TIMER__){clearTimeout(o.__LICENSE_MANAGER_RETRY_TIMER__);o.__LICENSE_MANAGER_RETRY_TIMER__=void 0}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{LICENSE_CACHE_DURATION as
|
|
1
|
+
"use strict";import{LICENSE_CACHE_DURATION as n}from"./config.js";import{realNow as r}from"./realNow.js";export function resolveAccountAccess(e,t=r()){const i=e.verifiedAt!==null&&Number.isFinite(e.verifiedAt)&&e.verifiedAt<=t?e.verifiedAt+n:null;if(e.initialized&&e.key&&e.tierSource!=="none"&&i!==null&&t<i){return{status:"admitted",reason:null,validUntil:i}}if(i!==null&&t>=i){return{status:"locked",reason:"verification_expired",validUntil:i}}if(!e.initialized||e.validating){return{status:"initializing",reason:"checking",validUntil:i}}return{status:"locked",reason:i!==null&&t>=i?"verification_expired":"account_required",validUntil:i}}
|
package/lib/module/api.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{KEYGEN_CONFIG as u}from"./config.js";const{apiUrl:
|
|
1
|
+
"use strict";import{KEYGEN_CONFIG as u}from"./config.js";import{realNow as l}from"./realNow.js";const{apiUrl:f}=u;export class LicenseTransportError extends Error{isTransient=true;constructor(e,n,i=null){super(e);this.name="LicenseTransportError";this.status=n;this.retryAfterMs=i}}export function isRateLimited(t){const e=t?.status;return e===429||e===402}export function backoffAfter(t,e,n){if(t.status===402)return e;return t.retryAfterMs??n}function m(t){const e=r=>{try{return t.headers?.get?.(r)??null}catch{return null}};const n=e("Retry-After");if(n){const r=Number(n);if(Number.isFinite(r)&&r>=0)return r*1e3;const a=Date.parse(n);if(Number.isFinite(a))return Math.max(0,a-l())}const i=Number(e("X-RateLimit-Reset"));if(Number.isFinite(i)&&i>0)return Math.max(0,i*1e3-l());return null}export function isTransientLicenseError(t){if(t instanceof LicenseTransportError)return true;if(t instanceof TypeError)return true;return typeof t==="object"&&t!==null&&t.isTransient===true}async function p(t){try{const e=await t.json();return e.errors?.[0]?.detail||`HTTP ${t.status}`}catch{return`HTTP ${t.status}`}}function d(){return{"Content-Type":"application/vnd.api+json",Accept:"application/vnd.api+json"}}async function T(t,e){const n=`${f}/validate`;const i={meta:{key:t}};let r;try{r=await fetch(n,{signal:e,method:"POST",headers:d(),body:JSON.stringify(i)})}catch(a){throw new LicenseTransportError(a instanceof Error?a.message:"Network request failed",null)}if(!r.ok){throw new LicenseTransportError(await p(r),r.status,r.status===429?m(r):null)}try{const a=await r.json();if(!a||typeof a!=="object"||typeof a.meta?.valid!=="boolean"||typeof a.meta?.code!=="string"||!a.meta.code)throw new Error("Missing license verdict");return a}catch{throw new LicenseTransportError("License server returned an unreadable response",r.status)}}export async function validateLicense(t){const e=typeof AbortController==="function"?new AbortController:null;let n;try{return await Promise.race([T(t,e?.signal),new Promise((i,r)=>{n=setTimeout(()=>{r(new LicenseTransportError("License verification timed out. Please retry.",null));e?.abort()},15e3)})])}finally{if(n)clearTimeout(n)}}export function isAcceptedValidation(t){if(!t.data)return false;const e=t.data.relationships?.product?.data?.id;if(e&&e!==u.productId)return false;if(t.meta.valid&&t.meta.code==="VALID")return true;return["OVERDUE","NO_MACHINE","NO_MACHINES","TOO_MANY_MACHINES","TOO_MANY_CORES","TOO_MANY_PROCESSES","FINGERPRINT_SCOPE_MISMATCH","HEARTBEAT_NOT_STARTED","HEARTBEAT_DEAD"].includes(t.meta.code)}export function machineCount(t){const e=t.data?.relationships?.machines?.meta?.count;return typeof e==="number"&&Number.isFinite(e)?e:0}export async function activateMachine(t,e,n,i,r){const a=`${f}/machines`;const o=await fetch(a,{method:"POST",headers:d(),body:JSON.stringify({licenseId:t,licenseKey:e,fingerprint:n,name:i,metadata:r||{}})});if(!o.ok){const s=await o.json();const c=s.errors?.[0]?.code;if(c==="FINGERPRINT_TAKEN"){throw new Error("FINGERPRINT_TAKEN")}if(c==="MACHINE_LIMIT_EXCEEDED"){throw new Error("MACHINE_LIMIT_EXCEEDED")}const E=s.errors?.[0]?.detail||`HTTP ${o.status}`;throw new Error(E)}return o.json()}export function parseValidationResult(t){const{meta:e,data:n}=t;return{valid:e.valid,code:e.code,detail:e.detail,metadata:n?.attributes?.metadata}}export function isFatalLicenseError(t){return["NOT_FOUND","SUSPENDED","EXPIRED","BANNED","PRODUCT_SCOPE_MISMATCH"].includes(t)}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
"use strict";/*!
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
2
|
+
* PROPRIETARY — Buoy Pro license enforcement. NOT open source.
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
|
5
|
+
* (https://buoy.gg/terms), not an OSS license.
|
|
6
|
+
*
|
|
7
|
+
* This file is part of the technological measure that controls access to paid
|
|
8
|
+
* Buoy Pro features. Modifying, patching, aliasing, stubbing, or otherwise
|
|
9
|
+
* altering it so that Pro features unlock without a valid license is a breach
|
|
10
|
+
* of the EULA and, in the United States, circumvention of an access control
|
|
11
|
+
* under 17 U.S.C. § 1201 — which applies whether or not any code is copied.
|
|
12
|
+
*
|
|
13
|
+
* Pro is $9/mo, and is free every weekend for anyone holding a key —
|
|
14
|
+
* including a free one (`npx buoy login`). Buy a key at
|
|
15
|
+
* https://buoy.gg or use it free on Saturday and Sunday.
|
|
16
|
+
*/const o="v2";const u=["v1"];const g="buoy.gg/pro:9f3c1d7a4b2e:license-cache";const f="\0";function i(n,r){let e=r>>>0;for(let t=0;t<n.length;t++){e^=n.charCodeAt(t);e=Math.imul(e,16777619)>>>0}return e>>>0}function a(n,r){const e=[r,n.licenseKey,n.licenseId,n.isPro?"1":"0",n.expiresAt??"",String(n.cachedAt)];if(r!=="v1"){e.push(n.tier??"")}e.push(g);return e.join(f)}function s(n,r){const e=a(n,r);const t=i(e,2166136261);const c=i(e,2135587861);return`${r}.${t.toString(16)}${c.toString(16)}`}export function cacheSignature(n){return s(n,o)}export function signCache(n){return{...n,sig:cacheSignature(n)}}export function verifyCacheSignature(n){if(!n||typeof n.sig!=="string"||n.sig.length===0){return false}if(n.sig===cacheSignature(n))return true;return u.some(r=>n.sig.startsWith(`${r}.`)&&n.sig===s(n,r))}
|
package/lib/module/config.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
"use strict";/*!
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
2
|
+
* PROPRIETARY — Buoy Pro license enforcement. NOT open source.
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
|
5
|
+
* (https://buoy.gg/terms), not an OSS license.
|
|
6
|
+
*
|
|
7
|
+
* This file configures the technological measure that controls access to paid
|
|
8
|
+
* Buoy Pro features. Modifying, patching, aliasing, stubbing, or otherwise
|
|
9
|
+
* altering it — including repointing `apiUrl` at a stand-in license server — so
|
|
10
|
+
* that Pro features unlock without a valid license is a breach of the EULA and,
|
|
11
|
+
* in the United States, circumvention of an access control under 17 U.S.C.
|
|
12
|
+
* § 1201, which applies whether or not any code is copied.
|
|
13
|
+
*
|
|
14
|
+
* Pro is $9/mo, and is free every weekend for anyone holding a key —
|
|
15
|
+
* including a free one (`npx buoy login`). Buy a key at
|
|
16
|
+
* https://buoy.gg or use it free on Saturday and Sunday.
|
|
17
|
+
*/export const KEYGEN_CONFIG={accountId:"b0eba0e8-e904-4906-b644-38f9aab57bed",productId:"bf67cb43-eeef-40ca-b308-e6e1b22c0eaa",apiUrl:"https://buoy.gg/api/license"};export const FREE_TOKEN_PUBLIC_KEY="3b546fc717a62683f3236c70167899a271bee3ffc04df6ec1eea60a394a2f1e9";export const KEYGEN_POLICIES={free:"394e3351-1249-4f73-807a-703408604c0e",solo:"fa5d3c8f-5379-40f1-b63e-ab8a974b2f28",business:"690c2212-8e54-426f-b4b4-002ee1c0ae2b"};export const LICENSE_CACHE_DURATION=30*24*60*60*1e3;export const LICENSE_REVALIDATION_INTERVAL=24*60*60*1e3;export const LICENSE_STORAGE_KEY="buoy-gg-license";export const DEVICE_FINGERPRINT_STORAGE_KEY="buoy-gg-device-fingerprint";export const LICENSE_LAUNCH_VALIDATION_TTL=60*60*1e3;export const LICENSE_TRANSIENT_RETRY_DELAYS=[5*1e3,20*1e3,60*1e3,5*60*1e3,15*60*1e3];export const LICENSE_RATE_LIMIT_DEFAULT_WAIT=60*1e3;export const LICENSE_QUOTA_COOLDOWN=60*60*1e3;export const LICENSE_VERDICT_CACHE_DURATION=24*60*60*1e3;export const LICENSE_FLEET_MACHINE_THRESHOLD=50;export const LICENSE_QUIET_VALIDATION_TTL=LICENSE_CACHE_DURATION;export const LICENSE_HOLD_STORAGE_KEY="buoy-gg-license-hold";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";export function generateUUID(){if(typeof crypto!=="undefined"&&crypto.randomUUID){return crypto.randomUUID()}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{const e=Math.random()*16|0;const r=n==="x"?e:e&3|8;return r.toString(16)})}export function isDevBundle(){if(typeof __DEV__!=="undefined")return __DEV__;try{if(typeof navigator!=="undefined"&&/electron/i.test(navigator.userAgent))return true}catch{}return typeof process!=="undefined"&&process.env?.NODE_ENV!=="production"}export function isSimulator(){return false}function
|
|
1
|
+
"use strict";export function generateUUID(){if(typeof crypto!=="undefined"&&crypto.randomUUID){return crypto.randomUUID()}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{const e=Math.random()*16|0;const r=n==="x"?e:e&3|8;return r.toString(16)})}export function isDevBundle(){if(typeof __DEV__!=="undefined")return __DEV__;try{if(typeof navigator!=="undefined"&&/electron/i.test(navigator.userAgent))return true}catch{}return typeof process!=="undefined"&&process.env?.NODE_ENV!=="production"}export function isSimulator(){return false}function u(){if(typeof navigator==="undefined"){return"unknown"}const n=navigator.userAgent.toLowerCase();const e=navigator.platform?.toLowerCase()||"";if(n.includes("electron")){if(e.includes("mac")||n.includes("mac")){return"electron-macos"}if(e.includes("win")||n.includes("win")){return"electron-windows"}if(e.includes("linux")||n.includes("linux")){return"electron-linux"}return"electron"}if(e.includes("mac")||n.includes("mac")){return"macos"}if(e.includes("win")||n.includes("win")){return"windows"}if(e.includes("linux")||n.includes("linux")){return"linux"}if(/iphone|ipad|ipod/.test(n)){return"ios-web"}if(n.includes("android")){return"android-web"}return"web"}function a(){if(typeof navigator==="undefined"){return"unknown"}const n=navigator.userAgent;const e=n.match(/Mac OS X ([\d_.]+)/);if(e){return e[1].replace(/_/g,".")}const r=n.match(/Windows NT ([\d.]+)/);if(r){const t={"10.0":"10/11","6.3":"8.1","6.2":"8","6.1":"7"};return t[r[1]]||r[1]}if(n.includes("Linux")){return"Linux"}return"unknown"}function c(){if(typeof navigator==="undefined"){return{name:"unknown",version:"unknown"}}const n=navigator.userAgent;const e=n.match(/Electron\/([\d.]+)/);if(e){return{name:"Electron",version:e[1]}}const r=n.match(/Chrome\/([\d.]+)/);if(r&&!n.includes("Edg")){return{name:"Chrome",version:r[1]}}const t=n.match(/Edg\/([\d.]+)/);if(t){return{name:"Edge",version:t[1]}}const o=n.match(/Firefox\/([\d.]+)/);if(o){return{name:"Firefox",version:o[1]}}const i=n.match(/Version\/([\d.]+).*Safari/);if(i){return{name:"Safari",version:i[1]}}return{name:"unknown",version:"unknown"}}export function getDeviceMetadata(){const n={platform:u(),osVersion:a(),isSimulator:"false"};const e=c();n.browser=e.name;n.browserVersion=e.version;if(typeof window!=="undefined"&&window.screen){n.screenResolution=`${window.screen.width}x${window.screen.height}`}if(typeof navigator!=="undefined"&&navigator.language){n.language=navigator.language}try{n.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone}catch{}return n}export function getDefaultDeviceName(){const n=u();const e=c();if(n.startsWith("electron")){const r=n.replace("electron-","").replace("electron","Desktop");return`${r.charAt(0).toUpperCase()+r.slice(1)} App`}if(e.name!=="unknown"){return`${e.name} Browser`}return"Web Browser"}
|
package/lib/module/freeToken.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";/*!
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
* PROPRIETARY — Buoy Pro license enforcement. NOT open source.
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
|
5
|
+
* (https://buoy.gg/terms), not an OSS license.
|
|
6
|
+
*/import i from"tweetnacl";import{FREE_TOKEN_PUBLIC_KEY as f}from"./config.js";export const FREE_TOKEN_PREFIX="BUOY1";const l=1;const a=1;const A="buoy-free-token-v1:";const h=22;const F=64;const p=/^BUOY1-([A-Z2-7]+)-([A-Z2-7]+)$/;export function isBuoyToken(n){return p.test(n.trim().toUpperCase())}const s="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";function y(n){let r="";let t=0;let e=0;for(const o of n){e=e<<8|o;t+=8;while(t>=5){r+=s[e>>>t-5&31];t-=5}}if(t>0)r+=s[e<<5-t&31];return r}function d(n){const r=[];let t=0;let e=0;for(const o of n){const c=s.indexOf(o);if(c===-1)return null;e=e<<5|c;t+=5;if(t>=8){r.push(e>>>t-8&255);t-=8}}return new Uint8Array(r)}function u(n){const r=n.trim().toLowerCase();const t=new Uint8Array(r.length/2);for(let e=0;e<t.length;e+=1)t[e]=parseInt(r.slice(e*2,e*2+2),16);return t}function g(n){let r="";for(const t of n)r+=t.toString(16).padStart(2,"0");return r}function m(n){if(typeof TextEncoder!=="undefined")return new TextEncoder().encode(n);const r=new Uint8Array(n.length);for(let t=0;t<n.length;t+=1)r[t]=n.charCodeAt(t)&255;return r}function T(n,r){const t=new Uint8Array(n.length+r.length);t.set(n,0);t.set(r,n.length);return t}function x(n){return T(m(A),n)}export function accountHashFor(n){return i.hash(m(n)).slice(0,16)}function U(n,r){const t=new Uint8Array(h);t[0]=l;t[1]=a;const e=Math.max(0,Math.min(4294967295,Math.floor(n)));t[2]=e>>>24&255;t[3]=e>>>16&255;t[4]=e>>>8&255;t[5]=e&255;t.set(r.slice(0,16),6);return t}export function mintFreeToken(n,r,t){const e=U(r/1e3,accountHashFor(n));const{secretKey:o}=i.sign.keyPair.fromSeed(u(t));const c=i.sign.detached(x(e),o);return`${FREE_TOKEN_PREFIX}-${y(e)}-${y(c)}`}export function publicKeyFor(n){return g(i.sign.keyPair.fromSeed(u(n)).publicKey)}let E=f;export function __setFreeTokenPublicKeyForTests(n){E=n??f}export function verifyFreeToken(n,r=E){const t=p.exec(n.trim().toUpperCase());if(!t)return null;const e=d(t[1]);const o=d(t[2]);if(!e||!o)return null;if(e.length!==h||o.length!==F)return null;if(e[0]!==l||e[1]!==a)return null;try{if(!i.sign.detached.verify(x(e),o,u(r)))return null}catch{return null}const c=(e[2]<<24>>>0)+(e[3]<<16)+(e[4]<<8)+e[5];return{tier:"free",issuedAt:c*1e3,accountHash:g(e.slice(6,22))}}
|
package/lib/module/hooks.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
"use strict";/*!
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
2
|
+
* PROPRIETARY — Buoy Pro license enforcement. NOT open source.
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
|
5
|
+
* (https://buoy.gg/terms), not an OSS license.
|
|
6
|
+
*
|
|
7
|
+
* This file is the technological measure that controls access to paid Buoy Pro
|
|
8
|
+
* features: `useIsPro()` here is the single gate every Buoy tool consults.
|
|
9
|
+
* Modifying, patching, aliasing, stubbing, or otherwise altering it so that Pro
|
|
10
|
+
* features unlock without a valid license is a breach of the EULA and, in the
|
|
11
|
+
* United States, circumvention of an access control under 17 U.S.C. § 1201 —
|
|
12
|
+
* which applies whether or not any code is copied.
|
|
13
|
+
*
|
|
14
|
+
* Pro is $9/mo, and is free every weekend for anyone holding a key —
|
|
15
|
+
* including a free one (`npx buoy login`). Buy a key at
|
|
16
|
+
* https://buoy.gg or use it free on Saturday and Sunday.
|
|
17
|
+
*/import{useState as d,useEffect as l,useCallback as o}from"react";import{LicenseManager as i}from"./LicenseManager.js";import{useWeekendFreePro as a,weekendPassAppliesTo as u}from"./weekendPro.js";export function useLicense(){const[n,e]=d(i.getState());l(()=>{const t=i.subscribe(r=>{e(i.getState())});i.initialize().then(()=>{e(i.getState())});return t},[]);const c=o(async t=>{const r=await i.setLicenseKey(t,{force:true});e(i.getState());return r},[]);const s=o(async()=>{await i.clearLicense();e(i.getState())},[]);return{...n,setLicenseKey:c,clearLicense:s}}export function useAccountAccess(){return useLicense().access}export function useTier(){const{tier:n,isInitialized:e}=useLicense();return e?n:"free"}export function useFeatureAccess(n){const{isPro:e,isInitialized:c,isValidating:s}=useLicense();const t=e;const r=!c||s;return{hasAccess:t,isPro:e,isLoading:r}}export function useIsPro(){const{isPro:n,isInitialized:e,access:c}=useLicense();const s=u(c.status==="admitted",a());return e&&n||s}export function useProAccess(){const{isPro:n,isInitialized:e,access:c}=useLicense();const s=e&&n;const t=u(c.status==="admitted",a())&&!s;const r=s?"licensed":t?"weekend":null;return{isPro:s||t,isLicensed:s,isWeekendFree:t,reason:r}}
|
package/lib/module/index.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
"use strict";/*!
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
2
|
+
* PROPRIETARY — Buoy Pro license enforcement. NOT open source.
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
|
5
|
+
* (https://buoy.gg/terms), not an OSS license.
|
|
6
|
+
*
|
|
7
|
+
* This package is the technological measure that controls access to paid Buoy
|
|
8
|
+
* Pro features. Modifying, patching, aliasing, stubbing, or otherwise altering
|
|
9
|
+
* it — including replacing this module via a bundler alias, package override,
|
|
10
|
+
* or postinstall patch — so that Pro features unlock without a valid license is
|
|
11
|
+
* a breach of the EULA and, in the United States, circumvention of an access
|
|
12
|
+
* control under 17 U.S.C. § 1201, which applies whether or not any code is
|
|
13
|
+
* copied.
|
|
14
|
+
*
|
|
15
|
+
* Pro is $9/mo, and is free every weekend for anyone holding a key —
|
|
16
|
+
* including a free one (`npx buoy login`). Buy a key at
|
|
17
|
+
* https://buoy.gg or use it free on Saturday and Sunday.
|
|
18
|
+
*/export{LicenseManager}from"./LicenseManager.js";export{DeviceRegistrationModal}from"./DeviceRegistrationModal.js";export{useLicense,useFeatureAccess,useIsPro,useProAccess,useTier}from"./hooks.js";export{useAccountAccess}from"./hooks.js";export{resolveAccountAccess}from"./accountAccess.js";export{LicenseTransportError,isTransientLicenseError}from"./api.js";export{isBuoyToken}from"./freeToken.js";export{isWeekendFreePro,useWeekendFreePro}from"./weekendPro.js";export async function setLicenseKey(e){const{LicenseManager:r}=await import("./LicenseManager");await r.initialize();return r.setLicenseKey(e)}function n(){const{isWeekendFreePro:e,weekendPassAppliesTo:r}=require("./weekendPro");const{LicenseManager:s}=require("./LicenseManager");return r(s.hasAccountAccess(),e())}export function isPro(){const{LicenseManager:e}=require("./LicenseManager");if(e.isPro())return true;return n()}export function hasEntitlement(e){const{LicenseManager:r}=require("./LicenseManager");if(r.hasEntitlement(e))return true;return n()}
|
package/lib/module/index.web.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
"use strict";/*!
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
2
|
+
* PROPRIETARY — Buoy Pro license enforcement. NOT open source.
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
|
5
|
+
* (https://buoy.gg/terms), not an OSS license.
|
|
6
|
+
*
|
|
7
|
+
* This package is the technological measure that controls access to paid Buoy
|
|
8
|
+
* Pro features. Modifying, patching, aliasing, stubbing, or otherwise altering
|
|
9
|
+
* it — including replacing this module via a bundler alias, package override,
|
|
10
|
+
* or postinstall patch — so that Pro features unlock without a valid license is
|
|
11
|
+
* a breach of the EULA and, in the United States, circumvention of an access
|
|
12
|
+
* control under 17 U.S.C. § 1201, which applies whether or not any code is
|
|
13
|
+
* copied.
|
|
14
|
+
*
|
|
15
|
+
* Pro is $9/mo, and is free every weekend for anyone holding a key —
|
|
16
|
+
* including a free one (`npx buoy login`). Buy a key at
|
|
17
|
+
* https://buoy.gg or use it free on Saturday and Sunday.
|
|
18
|
+
*/import{LicenseManager as r}from"./LicenseManager.js";import{isWeekendFreePro as o,weekendPassAppliesTo as n}from"./weekendPro.js";export{LicenseManager}from"./LicenseManager.js";export{useLicense,useFeatureAccess,useIsPro,useProAccess,useTier}from"./hooks.js";export{useAccountAccess}from"./hooks.js";export{resolveAccountAccess}from"./accountAccess.js";export{LicenseTransportError,isTransientLicenseError}from"./api.js";export{isBuoyToken}from"./freeToken.js";export{isWeekendFreePro,useWeekendFreePro}from"./weekendPro.js";export async function setLicenseKey(e){const{LicenseManager:s}=await import("./LicenseManager");await s.initialize();return s.setLicenseKey(e)}function t(){return n(r.hasAccountAccess(),o())}export function isPro(){if(r.isPro())return true;return t()}export function hasEntitlement(e){if(r.hasEntitlement(e))return true;return t()}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";export function realNow(){const o=globalThis.__buoyRealNow;return typeof o==="function"?o():Date.now()}
|
package/lib/module/storage.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const m="buoy-license";let c=null;let a=null;const
|
|
1
|
+
"use strict";const m="buoy-license";let c=null;let a=null;const i=new Map;function y(){if(c)return c;try{const t=require("expo-file-system/legacy");c=t?.default||t;if(c?.documentDirectory){return c}c=null}catch{}try{const t=require("expo-file-system");c=t?.default||t;if(c?.documentDirectory){return c}c=null}catch{}return null}function f(){const t=y();if(!t?.documentDirectory)return null;return`${t.documentDirectory}${m}/`}function l(t){const r=f();if(!r)return null;return`${r}${encodeURIComponent(t)}.json`}function g(){try{const t=require("@react-native-async-storage/async-storage");const r=t?.default||t;if(typeof r?.getItem==="function"&&typeof r.setItem==="function"&&typeof r.removeItem==="function"){return r}}catch{}return null}function I(){try{return typeof localStorage!=="undefined"&&!!localStorage}catch{return false}}export async function getLicenseStorage(){if(a)return a;const t=y();let r=null;if(t?.documentDirectory){a={async getItem(e){const n=l(e);if(!n)return null;try{const o=await t.getInfoAsync(n);if(!o.exists)return null;return await t.readAsStringAsync(n)}catch{return null}},async setItem(e,n){const o=f();const s=l(e);if(!o||!s)return;try{const u=await t.getInfoAsync(o);if(!u.exists){await t.makeDirectoryAsync(o,{intermediates:true})}await t.writeAsStringAsync(s,n)}catch(u){console.warn("[Buoy] License storage write failed:",u)}},async removeItem(e){const n=l(e);if(!n)return;try{await t.deleteAsync(n,{idempotent:true})}catch{}}}}else if(r=g()){const e=r;a={async getItem(n){try{return await e.getItem(n)}catch{return null}},async setItem(n,o){try{await e.setItem(n,o)}catch(s){console.warn("[Buoy] License storage write failed:",s)}},async removeItem(n){try{await e.removeItem(n)}catch{}}}}else if(I()){a={async getItem(e){try{return localStorage.getItem(e)}catch{return null}},async setItem(e,n){try{localStorage.setItem(e,n)}catch{}},async removeItem(e){try{localStorage.removeItem(e)}catch{}}}}else{a={async getItem(e){return i.get(e)??null},async setItem(e,n){i.set(e,n)},async removeItem(e){i.delete(e)}}}return a}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const
|
|
1
|
+
"use strict";const t=new Map;const r={async getItem(e){try{return localStorage.getItem(e)??t.get(e)??null}catch{return t.get(e)??null}},async setItem(e,c){t.set(e,c);try{localStorage.setItem(e,c)}catch{}},async removeItem(e){t.delete(e);try{localStorage.removeItem(e)}catch{}}};export async function getLicenseStorage(){return r}
|
package/lib/module/tier.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
"use strict";/*!
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
2
|
+
* PROPRIETARY — Buoy Pro license enforcement. NOT open source.
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
|
5
|
+
* (https://buoy.gg/terms), not an OSS license.
|
|
6
|
+
*
|
|
7
|
+
* This file is part of the technological measure that controls access to paid
|
|
8
|
+
* Buoy Pro features: it decides which tier a validated key grants. Modifying,
|
|
9
|
+
* patching, aliasing, stubbing, or otherwise altering it so that Pro features
|
|
10
|
+
* unlock without a valid license is a breach of the EULA and, in the United
|
|
11
|
+
* States, circumvention of an access control under 17 U.S.C. § 1201 — which
|
|
12
|
+
* applies whether or not any code is copied.
|
|
13
|
+
*
|
|
14
|
+
* Pro is $9/mo, and is free every weekend for anyone holding a key —
|
|
15
|
+
* including a free one (`npx buoy login`). Buy a key at
|
|
16
|
+
* https://buoy.gg or use it free on Saturday and Sunday.
|
|
17
|
+
*/import{KEYGEN_CONFIG as n,KEYGEN_POLICIES as r}from"./config.js";export function resolveTier(t){const e=t.relationships?.policy?.data?.id;if(e===r.free)return"free";if(e===r.solo||e===r.business){return"pro"}const o=t.attributes?.metadata?.plan;if(o==="free")return"free";return"pro"}export function tierAfterFatalError(t){return t==="EXPIRED"?"free":null}export function isRecognizedAccount(t){if(!t)return false;const e=t.relationships?.product?.data?.id;if(e)return e===n.productId;const o=t.relationships?.policy?.data?.id;return Object.values(r).some(i=>i===o)}
|
package/lib/module/weekendPro.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
"use strict";/*!
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
2
|
+
* PROPRIETARY — Buoy Pro license enforcement. NOT open source.
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
|
5
|
+
* (https://buoy.gg/terms), not an OSS license.
|
|
6
|
+
*
|
|
7
|
+
* Despite its small size, this file is a technological measure that controls
|
|
8
|
+
* access to paid Buoy Pro features: every `useIsPro()` gate in every Buoy tool
|
|
9
|
+
* unlocks when `isWeekendFreePro()` returns true. Modifying, patching,
|
|
10
|
+
* aliasing, stubbing, or otherwise altering it so that Pro features unlock
|
|
11
|
+
* without a valid license is a breach of the EULA and, in the United States,
|
|
12
|
+
* circumvention of an access control under 17 U.S.C. § 1201 — which applies
|
|
13
|
+
* whether or not any code is copied.
|
|
14
|
+
*
|
|
15
|
+
* Pro is $9/mo, and is free every weekend for anyone holding a key —
|
|
16
|
+
* including a free one (`npx buoy login`). Buy a key at
|
|
17
|
+
* https://buoy.gg or use it free on Saturday and Sunday.
|
|
18
|
+
*/import{useEffect as s,useState as a}from"react";import{realNow as c}from"./realNow.js";export function isWeekendFreePro(t=new Date(c())){const e=t.getDay();return e===0||e===6}export function useWeekendFreePro(){const[t,e]=a(()=>isWeekendFreePro());s(()=>{const o=setInterval(()=>{const r=isWeekendFreePro();e(n=>n===r?n:r)},60*1e3);return()=>clearInterval(o)},[]);return t}export function weekendPassAppliesTo(t,e){return e&&t}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The device's real clock.
|
|
3
|
+
*
|
|
4
|
+
* @buoy-gg/clock can override the APP's clock (Date.now, new Date). Buoy's
|
|
5
|
+
* own bookkeeping must keep real time regardless: license expiry, sync
|
|
6
|
+
* throttles and request deadlines would otherwise lock tools or stall when
|
|
7
|
+
* someone travels a month ahead. The clock package publishes the real clock
|
|
8
|
+
* on `globalThis.__buoyRealNow`; without it, Date.now is already real.
|
|
9
|
+
*/
|
|
10
|
+
export declare function realNow(): number;
|
|
11
|
+
//# sourceMappingURL=realNow.d.ts.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The device's real clock.
|
|
3
|
+
*
|
|
4
|
+
* @buoy-gg/clock can override the APP's clock (Date.now, new Date). Buoy's
|
|
5
|
+
* own bookkeeping must keep real time regardless: license expiry, sync
|
|
6
|
+
* throttles and request deadlines would otherwise lock tools or stall when
|
|
7
|
+
* someone travels a month ahead. The clock package publishes the real clock
|
|
8
|
+
* on `globalThis.__buoyRealNow`; without it, Date.now is already real.
|
|
9
|
+
*/
|
|
10
|
+
export declare function realNow(): number;
|
|
11
|
+
//# sourceMappingURL=realNow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{f as e}from"./chunk-ZSTLYSNF.mjs";export{e as LicenseManager};
|