@buoy-gg/license 7.0.84 → 7.0.85
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/sessionManager.js +2 -2
- package/lib/module/sessionManager.js +1 -1
- package/lib/typescript/commonjs/sessionManager.d.ts +26 -0
- package/lib/typescript/module/sessionManager.d.ts +26 -0
- package/lib/web/capacitor.mjs +1 -1
- package/lib/web/chunks/LicenseManager-KXCX4GG2.mjs +1 -0
- package/lib/web/chunks/chunk-KGEZ5TEJ.mjs +1 -0
- package/lib/web/chunks/chunk-U4JDBLRG.mjs +73 -0
- package/lib/web/chunks/chunk-YHWYXKID.mjs +1 -0
- package/lib/web/index.mjs +1 -1
- package/package.json +1 -1
- package/lib/web/chunks/LicenseManager-CJHAU3GD.mjs +0 -1
- package/lib/web/chunks/chunk-7T66ARUE.mjs +0 -73
- package/lib/web/chunks/chunk-D5RC3UOG.mjs +0 -1
- package/lib/web/chunks/chunk-J7MW3NXU.mjs +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.SessionManagerImpl=exports.SessionManager=exports.SessionError=exports.SESSION_STORAGE_PREFIX=exports.SESSION_RETRY_MS=exports.SESSION_REFRESH_LEAD_MS=exports.SESSION_OFFLINE_GRACE_MS=exports.SESSION_CALL_TIMEOUT_MS=exports.DEFAULT_SIGNIN_ORIGIN=void 0;var _storage=require("./storage");var _sessionToken=require("./sessionToken.js");var _realNow=require("./realNow.js");/*!
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.SessionManagerImpl=exports.SessionManager=exports.SessionError=exports.SESSION_STORAGE_PREFIX=exports.SESSION_RETRY_MS=exports.SESSION_REFRESH_LEAD_MS=exports.SESSION_PLAN_RETRY_MS=exports.SESSION_PLAN_CHECK_MS=exports.SESSION_OFFLINE_GRACE_MS=exports.SESSION_CALL_TIMEOUT_MS=exports.DEFAULT_SIGNIN_ORIGIN=void 0;var _storage=require("./storage");var _sessionToken=require("./sessionToken.js");var _realNow=require("./realNow.js");/*!
|
|
2
2
|
* PROPRIETARY — Buoy license enforcement. NOT open source.
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
|
5
5
|
* (https://buoy.gg/terms), not an OSS license.
|
|
6
|
-
*/const SESSION_STORAGE_PREFIX=exports.SESSION_STORAGE_PREFIX="@buoy/session:";const SESSION_OFFLINE_GRACE_MS=exports.SESSION_OFFLINE_GRACE_MS=7*24*60*60*1e3;const SESSION_REFRESH_LEAD_MS=exports.SESSION_REFRESH_LEAD_MS=6*60*60*1e3;const SESSION_RETRY_MS=exports.SESSION_RETRY_MS=5*60*1e3;const SESSION_CALL_TIMEOUT_MS=exports.SESSION_CALL_TIMEOUT_MS=15e3;const DEFAULT_SIGNIN_ORIGIN=exports.DEFAULT_SIGNIN_ORIGIN="https://buoy.gg";const MESSAGE_TYPE="buoy:signin";const POPUP_TIMEOUT_MS=10*60*1e3;class SessionError extends Error{constructor(e,t){super(t);this.code=e;this.name="SessionError"}}exports.SessionError=SessionError;function browserDeps(){const o=globalThis;return{fetch:(e,t)=>fetch(e,t),storage:_storage.getLicenseStorage,now:_realNow.realNow,random:e=>{const t=new Uint8Array(e);if(!o.crypto?.getRandomValues)throw new SessionError("not_configured","This platform has no secure random source.");return o.crypto.getRandomValues(t)},sha256:async e=>{if(!o.crypto?.subtle)throw new SessionError("not_configured","Sign-in needs a secure page (https or localhost).");return new Uint8Array(await o.crypto.subtle.digest("SHA-256",e))},openPopup:()=>{if(!o.window?.open)return null;const e=480;const t=640;const i=Math.max(0,(o.window.screenX??0)+((o.window.outerWidth??e)-e)/2);const r=Math.max(0,(o.window.screenY??0)+((o.window.outerHeight??t)-t)/2);return o.window.open("about:blank","buoy-signin",`popup,width=${e},height=${t},left=${i},top=${r}`)},onMessage:e=>{if(!o.window?.addEventListener)return()=>{};const t=i=>e({origin:i.origin,data:i.data});o.window.addEventListener("message",t);return()=>o.window?.removeEventListener("message",t)},withLock:(e,t)=>o.navigator?.locks?o.navigator.locks.request(e,t):t(),watch:e=>{const t=o.window;if(!t?.addEventListener)return()=>{};const i=n=>e.storage(n.key);const r=()=>{if(t.document?.visibilityState!=="hidden")e.wake()};t.addEventListener("storage",i);t.addEventListener("online",e.wake);t.document?.addEventListener?.("visibilitychange",r);return()=>{t.removeEventListener("storage",i);t.removeEventListener("online",e.wake);t.document?.removeEventListener?.("visibilitychange",r)}},setTimer:(e,t)=>setTimeout(e,Math.min(t,2147483647)),clearTimer:e=>clearTimeout(e)}}function defaultAudience(){const o=globalThis.location;if(!o?.origin||!/^https?:$/.test(o.protocol??""))return void 0;return o.origin}class SessionManagerImpl{signinOrigin=DEFAULT_SIGNIN_ORIGIN;current=null;claims=null;listeners=new Set;timer=null;refreshing=null;loaded=null;unwatch=null;limitTimer=null;epoch=0;constructor(e){this.deps=e??browserDeps();this.audience=defaultAudience()}get origin(){return this.signinOrigin}configure(e){if(e.audience!==void 0)this.audience=e.audience;if(e.signinOrigin!==void 0)this.signinOrigin=e.signinOrigin.replace(/\/$/,"");this.reset()}reset(){this.unwatch?.();this.unwatch=null;this.epoch+=1;if(this.limitTimer!==null)this.deps.clearTimer(this.limitTimer);this.limitTimer=null;if(this.timer!==null)this.deps.clearTimer(this.timer);this.timer=null;this.current=null;this.claims=null;this.loaded=null;this.refreshing=null}get storageKey(){return SESSION_STORAGE_PREFIX+(this.audience??"")}subscribe(e){this.listeners.add(e);return()=>this.listeners.delete(e)}notify(){for(const e of[...this.listeners]){try{e()}catch(t){console.warn("[Buoy] sign-in listener error:",t)}}}getAccessToken(){const e=this.getStatus();return e.state==="active"&&!e.grace?this.current?.accessToken??null:null}getStatus(){const e=this.claims;if(!e)return{state:"signed_out"};const t=e.exp*1e3;const i=this.deps.now();if(i<(e.iat-_sessionToken.SESSION_CLOCK_SKEW_SECONDS)*1e3)return{state:"signed_out"};if(i<t)return{state:"active",claims:e,grace:false,validUntil:t};if(i<t+SESSION_OFFLINE_GRACE_MS){return{state:"active",claims:e,grace:true,validUntil:t+SESSION_OFFLINE_GRACE_MS}}return{state:"signed_out"}}load(){if(!this.loaded)this.loaded=this.loadOnce();return this.loaded}async loadOnce(){if(!this.audience)return;this.unwatch??=this.deps.watch?.({storage:t=>{if(t===null||t===this.storageKey)void this.sync()},wake:()=>{if(this.claims)void this.refresh()}})??null;const e=await this.read();if(e&&this.adopt(e)){this.notify();this.schedule()}}async sync(){if(!this.audience)return;const e=await this.read();if(!e){if(this.current)this.clearLocal();return}if(e.refreshToken!==this.current?.refreshToken&&this.adopt(e)){this.notify();this.schedule()}}async read(){try{const e=await(await this.deps.storage()).getItem(this.storageKey);if(!e)return null;const t=JSON.parse(e);return t?.v===1&&typeof t.accessToken==="string"&&typeof t.refreshToken==="string"?t:null}catch{return null}}async write(e){const t=await this.deps.storage();if(e)await t.setItem(this.storageKey,JSON.stringify(e));else await t.removeItem(this.storageKey)}adopt(e){if(!this.audience)return false;const t=(0,_sessionToken.verifySessionToken)(e.accessToken,{audience:this.audience,ignoreTime:true});const i=t.ok?t.claims:null;if(!i)return false;this.current=e;this.claims=i;return true}armLimit(){if(this.limitTimer!==null)this.deps.clearTimer(this.limitTimer);this.limitTimer=null;if(!this.claims)return;const e=this.claims.exp*1e3;const t=this.deps.now();const i=t<e?e:t<e+SESSION_OFFLINE_GRACE_MS?e+SESSION_OFFLINE_GRACE_MS:null;if(i===null)return;this.limitTimer=this.deps.setTimer(()=>{this.limitTimer=null;this.notify();this.armLimit()},i-t)}call(e,t){return new Promise((i,r)=>{const n=this.deps.setTimer(()=>r(new Error("timeout")),SESSION_CALL_TIMEOUT_MS);this.deps.fetch(e,t).then(s=>{this.deps.clearTimer(n);i(s)},s=>{this.deps.clearTimer(n);r(s)})})}schedule(){this.armLimit();if(this.timer!==null)this.deps.clearTimer(this.timer);this.timer=null;if(!this.claims)return;const e=this.claims.exp*1e3-SESSION_REFRESH_LEAD_MS-this.deps.now();this.timer=this.deps.setTimer(()=>{this.timer=null;void this.refresh()},Math.max(0,e))}refresh(e=false){if(!this.refreshing){this.refreshing=this.deps.withLock(this.lockName,()=>this.refreshLocked(e)).catch(()=>this.retryLater()).finally(()=>{this.refreshing=null})}return this.refreshing}get lockName(){return`buoy-session:${this.audience??""}`}async refreshLocked(e){const t=this.epoch;const i=await this.read();if(!i){if(this.current)this.clearLocal();return}if(i.refreshToken!==this.current?.refreshToken){if(this.adopt(i)){this.notify();this.schedule();return}}if(!this.claims)return;if(!e&&this.claims.exp*1e3-this.deps.now()>SESSION_REFRESH_LEAD_MS){this.schedule();return}let r;let n;try{const s=await this.call(`${this.signinOrigin}/api/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refresh_token:i.refreshToken,audience:this.audience})});r=s.status;n=await s.json().catch(()=>null)}catch{this.retryLater();return}if(t!==this.epoch)return;if(r===200&&n&&typeof n.access_token==="string"&&typeof n.refresh_token==="string"){const s={v:1,accessToken:n.access_token,refreshToken:n.refresh_token};if(this.adopt(s)){await this.write(s);this.notify();this.schedule();return}}if(r===400||r===401||r===403){await this.write(null);this.clearLocal();return}this.retryLater()}retryLater(){this.armLimit();if(this.timer!==null)this.deps.clearTimer(this.timer);this.timer=this.deps.setTimer(()=>{this.timer=null;void this.refresh(true)},SESSION_RETRY_MS);this.notify()}clearLocal(){if(this.timer!==null)this.deps.clearTimer(this.timer);this.timer=null;if(this.limitTimer!==null)this.deps.clearTimer(this.limitTimer);this.limitTimer=null;this.current=null;this.claims=null;this.notify()}async signIn(){if(!this.audience)throw new SessionError("not_configured","Sign-in needs a web page or a configured app id.");const e=this.deps.openPopup();if(!e)throw new SessionError("popup_blocked","The browser blocked the sign-in window. Allow pop-ups for this site and try again.");try{return await this.signInWith((t,i)=>new Promise((r,n)=>{e.location.href=t;const s=this.deps.now();let l=null;const h=u=>{if(l!==null)this.deps.clearTimer(l);a();u()};const a=this.deps.onMessage(u=>{if(u.origin!==this.signinOrigin)return;const d=u.data;if(!d||d.type!==MESSAGE_TYPE||d.state!==i)return;if(typeof d.code==="string")h(()=>r(d.code));else h(()=>n(new SessionError("access_denied","Sign-in was cancelled.")))});const c=()=>{if(e.closed)return h(()=>n(new SessionError("popup_closed","The sign-in window was closed.")));if(this.deps.now()-s>POPUP_TIMEOUT_MS)return h(()=>n(new SessionError("timeout","Sign-in took too long.")));l=this.deps.setTimer(c,500)};l=this.deps.setTimer(c,500)}))}finally{try{if(!e.closed)e.close()}catch{}}}async signInWith(e){const t=this.audience;if(!t)throw new SessionError("not_configured","Sign-in needs a web page or a configured app id.");const i=(0,_sessionToken.base64urlEncode)(this.deps.random(32));const r=(0,_sessionToken.base64urlEncode)(this.deps.random(16));const n=(0,_sessionToken.base64urlEncode)(await this.deps.sha256(new TextEncoder().encode(i)));const s=`${this.signinOrigin}/auth/authorize?audience=${encodeURIComponent(t)}&code_challenge=${n}&code_challenge_method=S256&state=${r}`;const l=await e(s,r);let h;try{h=await this.call(`${this.signinOrigin}/api/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:l,code_verifier:i,audience:t})})}catch{throw new SessionError("network","Buoy could not be reached. Check your connection and try again.")}const a=await h.json().catch(()=>null);if(h.status!==200||!a||typeof a.access_token!=="string"||typeof a.refresh_token!=="string"){const c=a&&typeof a.error_description==="string"?a.error_description:"Buoy did not accept this sign-in.";throw new SessionError(h.status===503?"unavailable":"rejected",c)}return this.finishSignIn(a.access_token,a.refresh_token)}async finishSignIn(e,t){const i={v:1,accessToken:e,refreshToken:t};this.epoch+=1;if(!this.adopt(i))throw new SessionError("rejected","Buoy sent a sign-in this app could not check.");await this.write(i);await this.load();this.notify();this.schedule();return this.getStatus()}async signInWithCode(e,t={}){const i=this.audience;if(!i)throw new SessionError("not_configured","Sign-in with a code needs this app's id (app:com.example.app).");const r=(a,c)=>this.call(`${this.signinOrigin}/api/auth/device/${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(c)});let n;try{n=await r("start",{audience:i})}catch{throw new SessionError("network","Buoy could not be reached. Check your connection and try again.")}const s=await n.json().catch(()=>null);if(n.status!==200||!s||typeof s.device_code!=="string"||typeof s.user_code!=="string"||typeof s.verification_uri!=="string"||typeof s.verification_uri_complete!=="string"){const a=s&&typeof s.error_description==="string"?s.error_description:"Buoy could not start a sign-in.";throw new SessionError(n.status===503?"unavailable":"rejected",a)}const l=this.deps.now()+(Number(s.expires_in)||600)*1e3;let h=Math.max(5,Number(s.interval)||5)*1e3;e({userCode:s.user_code,verificationUri:s.verification_uri,verificationUriComplete:s.verification_uri_complete,expiresAt:l});for(;;){await this.wait(h,t.signal);if(this.deps.now()>l)throw new SessionError("timeout","The code ran out. Start again for a new one.");let a;try{a=await r("poll",{device_code:s.device_code})}catch{continue}const c=await a.json().catch(()=>null);if(a.status===200&&c&&typeof c.access_token==="string"&&typeof c.refresh_token==="string"){return this.finishSignIn(c.access_token,c.refresh_token)}const u=c&&typeof c.error==="string"?c.error:"";if(u==="authorization_pending"||a.status>=500)continue;if(u==="slow_down"||a.status===429){h+=5e3;continue}if(u==="access_denied")throw new SessionError("access_denied","The sign-in was turned down on buoy.gg.");if(u==="expired_token")throw new SessionError("timeout","The code ran out. Start again for a new one.");const d=c&&typeof c.error_description==="string"?c.error_description:"Buoy did not accept this sign-in.";throw new SessionError("rejected",d)}}wait(e,t){return new Promise((i,r)=>{const n=()=>new SessionError("access_denied","Sign-in was cancelled.");if(t?.aborted)return r(n());const s=()=>{this.deps.clearTimer(l);r(n())};const l=this.deps.setTimer(()=>{t?.removeEventListener?.("abort",s);i()},e);t?.addEventListener?.("abort",s)})}async signOut(){this.epoch+=1;const e=this.current;this.clearLocal();let t=e;try{await this.deps.withLock(this.lockName,async()=>{t=await this.read()??e;await this.write(null)})}catch{await this.write(null).catch(()=>{})}if(!t)return;try{await this.call(`${this.signinOrigin}/api/auth/revoke`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refresh_token:t.refreshToken})})}catch{}}}exports.SessionManagerImpl=SessionManagerImpl;const SessionManager=exports.SessionManager=new SessionManagerImpl;
|
|
6
|
+
*/const SESSION_STORAGE_PREFIX=exports.SESSION_STORAGE_PREFIX="@buoy/session:";const SESSION_OFFLINE_GRACE_MS=exports.SESSION_OFFLINE_GRACE_MS=7*24*60*60*1e3;const SESSION_REFRESH_LEAD_MS=exports.SESSION_REFRESH_LEAD_MS=6*60*60*1e3;const SESSION_PLAN_CHECK_MS=exports.SESSION_PLAN_CHECK_MS=5*60*1e3;const SESSION_PLAN_RETRY_MS=exports.SESSION_PLAN_RETRY_MS=5*1e3;const SESSION_RETRY_MS=exports.SESSION_RETRY_MS=5*60*1e3;const SESSION_CALL_TIMEOUT_MS=exports.SESSION_CALL_TIMEOUT_MS=15e3;const DEFAULT_SIGNIN_ORIGIN=exports.DEFAULT_SIGNIN_ORIGIN="https://buoy.gg";const MESSAGE_TYPE="buoy:signin";const POPUP_TIMEOUT_MS=10*60*1e3;class SessionError extends Error{constructor(e,t){super(t);this.code=e;this.name="SessionError"}}exports.SessionError=SessionError;function browserDeps(){const n=globalThis;return{fetch:(e,t)=>fetch(e,t),storage:_storage.getLicenseStorage,now:_realNow.realNow,random:e=>{const t=new Uint8Array(e);if(!n.crypto?.getRandomValues)throw new SessionError("not_configured","This platform has no secure random source.");return n.crypto.getRandomValues(t)},sha256:async e=>{if(!n.crypto?.subtle)throw new SessionError("not_configured","Sign-in needs a secure page (https or localhost).");return new Uint8Array(await n.crypto.subtle.digest("SHA-256",e))},openPopup:()=>{if(!n.window?.open)return null;const e=480;const t=640;const i=Math.max(0,(n.window.screenX??0)+((n.window.outerWidth??e)-e)/2);const o=Math.max(0,(n.window.screenY??0)+((n.window.outerHeight??t)-t)/2);return n.window.open("about:blank","buoy-signin",`popup,width=${e},height=${t},left=${i},top=${o}`)},onMessage:e=>{if(!n.window?.addEventListener)return()=>{};const t=i=>e({origin:i.origin,data:i.data});n.window.addEventListener("message",t);return()=>n.window?.removeEventListener("message",t)},withLock:(e,t)=>n.navigator?.locks?n.navigator.locks.request(e,t):t(),checksPlan:!n.window?.addEventListener||!!n.navigator?.locks,watch:e=>{const t=n.window;if(!t?.addEventListener)return watchAppState(e.wake);const i=c=>e.storage(c.key);const o=()=>{if(t.document?.visibilityState!=="hidden")e.wake()};t.addEventListener("storage",i);t.addEventListener("online",e.wake);t.document?.addEventListener?.("visibilitychange",o);return()=>{t.removeEventListener("storage",i);t.removeEventListener("online",e.wake);t.document?.removeEventListener?.("visibilitychange",o)}},setTimer:(e,t)=>setTimeout(e,Math.min(t,2147483647)),clearTimer:e=>clearTimeout(e)}}function watchAppState(n){try{const{AppState:e}=require("react-native");const t=e?.addEventListener?.("change",i=>{if(i==="active")n()});return()=>t?.remove()}catch{return()=>{}}}function defaultAudience(){const n=globalThis.location;if(!n?.origin||!/^https?:$/.test(n.protocol??""))return void 0;return n.origin}class SessionManagerImpl{signinOrigin=DEFAULT_SIGNIN_ORIGIN;current=null;claims=null;listeners=new Set;timer=null;refreshing=null;loaded=null;unwatch=null;limitTimer=null;epoch=0;constructor(e){this.deps=e??browserDeps();this.audience=defaultAudience()}get origin(){return this.signinOrigin}configure(e){if(e.audience!==void 0)this.audience=e.audience;if(e.signinOrigin!==void 0)this.signinOrigin=e.signinOrigin.replace(/\/$/,"");this.reset()}reset(){this.planRetries=0;this.unwatch?.();this.unwatch=null;this.epoch+=1;if(this.limitTimer!==null)this.deps.clearTimer(this.limitTimer);this.limitTimer=null;if(this.timer!==null)this.deps.clearTimer(this.timer);this.timer=null;this.current=null;this.claims=null;this.loaded=null;this.refreshing=null}get storageKey(){return SESSION_STORAGE_PREFIX+(this.audience??"")}subscribe(e){this.listeners.add(e);return()=>this.listeners.delete(e)}notify(){for(const e of[...this.listeners]){try{e()}catch(t){console.warn("[Buoy] sign-in listener error:",t)}}}getAccessToken(){const e=this.getStatus();return e.state==="active"&&!e.grace?this.current?.accessToken??null:null}getStatus(){const e=this.claims;if(!e)return{state:"signed_out"};const t=e.exp*1e3;const i=this.deps.now();if(i<(e.iat-_sessionToken.SESSION_CLOCK_SKEW_SECONDS)*1e3)return{state:"signed_out"};if(i<t)return{state:"active",claims:e,grace:false,validUntil:t};if(i<t+SESSION_OFFLINE_GRACE_MS){return{state:"active",claims:e,grace:true,validUntil:t+SESSION_OFFLINE_GRACE_MS}}return{state:"signed_out"}}load(){if(!this.loaded)this.loaded=this.loadOnce();return this.loaded}async loadOnce(){if(!this.audience)return;this.unwatch??=this.deps.watch?.({storage:t=>{if(t===null||t===this.storageKey)void this.sync()},wake:()=>{if(this.deps.checksPlan)void this.checkPlan();else if(this.claims)void this.refresh()}})??null;const e=await this.read();if(e&&this.adopt(e)){this.notify();this.schedule();if(this.deps.checksPlan)void this.checkPlan()}}async sync(){if(!this.audience)return;const e=await this.read();if(!e){if(this.current)this.clearLocal();return}if(e.refreshToken!==this.current?.refreshToken&&this.adopt(e)){this.notify();this.schedule()}}async read(){try{const e=await(await this.deps.storage()).getItem(this.storageKey);if(!e)return null;const t=JSON.parse(e);return t?.v===1&&typeof t.accessToken==="string"&&typeof t.refreshToken==="string"?t:null}catch{return null}}async write(e){const t=await this.deps.storage();if(e)await t.setItem(this.storageKey,JSON.stringify(e));else await t.removeItem(this.storageKey)}adopt(e){if(!this.audience)return false;const t=(0,_sessionToken.verifySessionToken)(e.accessToken,{audience:this.audience,ignoreTime:true});const i=t.ok?t.claims:null;if(!i)return false;this.current=e;this.claims=i;return true}armLimit(){if(this.limitTimer!==null)this.deps.clearTimer(this.limitTimer);this.limitTimer=null;if(!this.claims)return;const e=this.claims.exp*1e3;const t=this.deps.now();const i=t<e?e:t<e+SESSION_OFFLINE_GRACE_MS?e+SESSION_OFFLINE_GRACE_MS:null;if(i===null)return;this.limitTimer=this.deps.setTimer(()=>{this.limitTimer=null;this.notify();this.armLimit()},i-t)}call(e,t){return new Promise((i,o)=>{const c=this.deps.setTimer(()=>o(new Error("timeout")),SESSION_CALL_TIMEOUT_MS);this.deps.fetch(e,t).then(s=>{this.deps.clearTimer(c);i(s)},s=>{this.deps.clearTimer(c);o(s)})})}schedule(){this.armLimit();if(this.timer!==null)this.deps.clearTimer(this.timer);this.timer=null;if(!this.claims)return;const e=this.claims.exp*1e3-SESSION_REFRESH_LEAD_MS-this.deps.now();this.timer=this.deps.setTimer(()=>{this.timer=null;void this.refresh()},Math.max(0,e))}refresh(e=false){return this.startRefresh(()=>this.refreshLocked(e))}checkPlan(e=SESSION_PLAN_CHECK_MS){return this.startRefresh(()=>this.refreshLocked(false,e))}planRetries=0;retryPlanCheck(){if(this.planRetries>=2){this.planRetries=0;this.schedule();return}this.planRetries+=1;if(this.timer!==null)this.deps.clearTimer(this.timer);this.timer=this.deps.setTimer(()=>{this.timer=null;void this.checkPlan(0)},SESSION_PLAN_RETRY_MS)}startRefresh(e){if(!this.refreshing){this.refreshing=this.deps.withLock(this.lockName,e).catch(()=>this.retryLater()).finally(()=>{this.refreshing=null})}return this.refreshing}get lockName(){return`buoy-session:${this.audience??""}`}async refreshLocked(e,t){const i=this.epoch;const o=await this.read();if(!o){if(this.current)this.clearLocal();return}if(o.refreshToken!==this.current?.refreshToken){if(this.adopt(o)){this.notify();this.schedule();return}}if(!this.claims)return;const c=this.claims.exp*1e3-this.deps.now()>SESSION_REFRESH_LEAD_MS;const s=!e&&c&&t!==void 0;const d=s&&this.planRetries>0&&this.timer===null;const l=s&&this.deps.now()-this.claims.iat*1e3>=t;if(!e&&c&&!l&&!d){if(!this.planRetries)this.schedule();return}const a=()=>s?this.retryPlanCheck():this.retryLater();let r;let h;try{const u=await this.call(`${this.signinOrigin}/api/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refresh_token:o.refreshToken,audience:this.audience})});r=u.status;h=await u.json().catch(()=>null)}catch{if(i===this.epoch)a();return}if(i!==this.epoch)return;if(r===200&&h&&typeof h.access_token==="string"&&typeof h.refresh_token==="string"){const u={v:1,accessToken:h.access_token,refreshToken:h.refresh_token};if(this.adopt(u)){this.planRetries=0;await this.write(u);this.notify();this.schedule();return}}if(r===400||r===401||r===403){await this.write(null);this.clearLocal();return}a()}retryLater(){this.armLimit();if(this.timer!==null)this.deps.clearTimer(this.timer);this.timer=this.deps.setTimer(()=>{this.timer=null;void this.refresh(true)},SESSION_RETRY_MS);this.notify()}clearLocal(){this.planRetries=0;if(this.timer!==null)this.deps.clearTimer(this.timer);this.timer=null;if(this.limitTimer!==null)this.deps.clearTimer(this.limitTimer);this.limitTimer=null;this.current=null;this.claims=null;this.notify()}async signIn(){if(!this.audience)throw new SessionError("not_configured","Sign-in needs a web page or a configured app id.");const e=this.deps.openPopup();if(!e)throw new SessionError("popup_blocked","The browser blocked the sign-in window. Allow pop-ups for this site and try again.");try{return await this.signInWith((t,i)=>new Promise((o,c)=>{e.location.href=t;const s=this.deps.now();let d=null;const l=h=>{if(d!==null)this.deps.clearTimer(d);a();h()};const a=this.deps.onMessage(h=>{if(h.origin!==this.signinOrigin)return;const u=h.data;if(!u||u.type!==MESSAGE_TYPE||u.state!==i)return;if(typeof u.code==="string")l(()=>o(u.code));else l(()=>c(new SessionError("access_denied","Sign-in was cancelled.")))});const r=()=>{if(e.closed)return l(()=>c(new SessionError("popup_closed","The sign-in window was closed.")));if(this.deps.now()-s>POPUP_TIMEOUT_MS)return l(()=>c(new SessionError("timeout","Sign-in took too long.")));d=this.deps.setTimer(r,500)};d=this.deps.setTimer(r,500)}))}finally{try{if(!e.closed)e.close()}catch{}}}async signInWith(e){const t=this.audience;if(!t)throw new SessionError("not_configured","Sign-in needs a web page or a configured app id.");const i=(0,_sessionToken.base64urlEncode)(this.deps.random(32));const o=(0,_sessionToken.base64urlEncode)(this.deps.random(16));const c=(0,_sessionToken.base64urlEncode)(await this.deps.sha256(new TextEncoder().encode(i)));const s=`${this.signinOrigin}/auth/authorize?audience=${encodeURIComponent(t)}&code_challenge=${c}&code_challenge_method=S256&state=${o}`;const d=await e(s,o);let l;try{l=await this.call(`${this.signinOrigin}/api/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:d,code_verifier:i,audience:t})})}catch{throw new SessionError("network","Buoy could not be reached. Check your connection and try again.")}const a=await l.json().catch(()=>null);if(l.status!==200||!a||typeof a.access_token!=="string"||typeof a.refresh_token!=="string"){const r=a&&typeof a.error_description==="string"?a.error_description:"Buoy did not accept this sign-in.";throw new SessionError(l.status===503?"unavailable":"rejected",r)}return this.finishSignIn(a.access_token,a.refresh_token)}async finishSignIn(e,t){const i={v:1,accessToken:e,refreshToken:t};this.epoch+=1;if(!this.adopt(i))throw new SessionError("rejected","Buoy sent a sign-in this app could not check.");await this.write(i);await this.load();this.notify();this.schedule();return this.getStatus()}async signInWithCode(e,t={}){const i=this.audience;if(!i)throw new SessionError("not_configured","Sign-in with a code needs this app's id (app:com.example.app).");const o=(a,r)=>this.call(`${this.signinOrigin}/api/auth/device/${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)});let c;try{c=await o("start",{audience:i})}catch{throw new SessionError("network","Buoy could not be reached. Check your connection and try again.")}const s=await c.json().catch(()=>null);if(c.status!==200||!s||typeof s.device_code!=="string"||typeof s.user_code!=="string"||typeof s.verification_uri!=="string"||typeof s.verification_uri_complete!=="string"){const a=s&&typeof s.error_description==="string"?s.error_description:"Buoy could not start a sign-in.";throw new SessionError(c.status===503?"unavailable":"rejected",a)}const d=this.deps.now()+(Number(s.expires_in)||600)*1e3;let l=Math.max(5,Number(s.interval)||5)*1e3;e({userCode:s.user_code,verificationUri:s.verification_uri,verificationUriComplete:s.verification_uri_complete,expiresAt:d});for(;;){await this.wait(l,t.signal);if(this.deps.now()>d)throw new SessionError("timeout","The code ran out. Start again for a new one.");let a;try{a=await o("poll",{device_code:s.device_code})}catch{continue}const r=await a.json().catch(()=>null);if(a.status===200&&r&&typeof r.access_token==="string"&&typeof r.refresh_token==="string"){return this.finishSignIn(r.access_token,r.refresh_token)}const h=r&&typeof r.error==="string"?r.error:"";if(h==="authorization_pending"||a.status>=500)continue;if(h==="slow_down"||a.status===429){l+=5e3;continue}if(h==="access_denied")throw new SessionError("access_denied","The sign-in was turned down on buoy.gg.");if(h==="expired_token")throw new SessionError("timeout","The code ran out. Start again for a new one.");const u=r&&typeof r.error_description==="string"?r.error_description:"Buoy did not accept this sign-in.";throw new SessionError("rejected",u)}}wait(e,t){return new Promise((i,o)=>{const c=()=>new SessionError("access_denied","Sign-in was cancelled.");if(t?.aborted)return o(c());const s=()=>{this.deps.clearTimer(d);o(c())};const d=this.deps.setTimer(()=>{t?.removeEventListener?.("abort",s);i()},e);t?.addEventListener?.("abort",s)})}async signOut(){this.epoch+=1;const e=this.current;this.clearLocal();let t=e;try{await this.deps.withLock(this.lockName,async()=>{t=await this.read()??e;await this.write(null)})}catch{await this.write(null).catch(()=>{})}if(!t)return;try{await this.call(`${this.signinOrigin}/api/auth/revoke`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refresh_token:t.refreshToken})})}catch{}}}exports.SessionManagerImpl=SessionManagerImpl;const SessionManager=exports.SessionManager=new SessionManagerImpl;
|
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
|
5
5
|
* (https://buoy.gg/terms), not an OSS license.
|
|
6
|
-
*/import{getLicenseStorage as p}from"./storage";import{base64urlEncode as f,verifySessionToken as g,SESSION_CLOCK_SKEW_SECONDS as w}from"./sessionToken.js";import{realNow as m}from"./realNow.js";export const SESSION_STORAGE_PREFIX="@buoy/session:";export const SESSION_OFFLINE_GRACE_MS=7*24*60*60*1e3;export const SESSION_REFRESH_LEAD_MS=6*60*60*1e3;export const SESSION_RETRY_MS=5*60*1e3;export const SESSION_CALL_TIMEOUT_MS=15e3;export const DEFAULT_SIGNIN_ORIGIN="https://buoy.gg";const y="buoy:signin";const T=10*60*1e3;export class SessionError extends Error{constructor(e,t){super(t);this.code=e;this.name="SessionError"}}function _(){const o=globalThis;return{fetch:(e,t)=>fetch(e,t),storage:p,now:m,random:e=>{const t=new Uint8Array(e);if(!o.crypto?.getRandomValues)throw new SessionError("not_configured","This platform has no secure random source.");return o.crypto.getRandomValues(t)},sha256:async e=>{if(!o.crypto?.subtle)throw new SessionError("not_configured","Sign-in needs a secure page (https or localhost).");return new Uint8Array(await o.crypto.subtle.digest("SHA-256",e))},openPopup:()=>{if(!o.window?.open)return null;const e=480;const t=640;const i=Math.max(0,(o.window.screenX??0)+((o.window.outerWidth??e)-e)/2);const r=Math.max(0,(o.window.screenY??0)+((o.window.outerHeight??t)-t)/2);return o.window.open("about:blank","buoy-signin",`popup,width=${e},height=${t},left=${i},top=${r}`)},onMessage:e=>{if(!o.window?.addEventListener)return()=>{};const t=i=>e({origin:i.origin,data:i.data});o.window.addEventListener("message",t);return()=>o.window?.removeEventListener("message",t)},withLock:(e,t)=>o.navigator?.locks?o.navigator.locks.request(e,t):t(),watch:e=>{const t=o.window;if(!t?.addEventListener)return()=>{};const i=n=>e.storage(n.key);const r=()=>{if(t.document?.visibilityState!=="hidden")e.wake()};t.addEventListener("storage",i);t.addEventListener("online",e.wake);t.document?.addEventListener?.("visibilitychange",r);return()=>{t.removeEventListener("storage",i);t.removeEventListener("online",e.wake);t.document?.removeEventListener?.("visibilitychange",r)}},setTimer:(e,t)=>setTimeout(e,Math.min(t,2147483647)),clearTimer:e=>clearTimeout(e)}}function S(){const o=globalThis.location;if(!o?.origin||!/^https?:$/.test(o.protocol??""))return void 0;return o.origin}export class SessionManagerImpl{signinOrigin=DEFAULT_SIGNIN_ORIGIN;current=null;claims=null;listeners=new Set;timer=null;refreshing=null;loaded=null;unwatch=null;limitTimer=null;epoch=0;constructor(e){this.deps=e??_();this.audience=S()}get origin(){return this.signinOrigin}configure(e){if(e.audience!==void 0)this.audience=e.audience;if(e.signinOrigin!==void 0)this.signinOrigin=e.signinOrigin.replace(/\/$/,"");this.reset()}reset(){this.unwatch?.();this.unwatch=null;this.epoch+=1;if(this.limitTimer!==null)this.deps.clearTimer(this.limitTimer);this.limitTimer=null;if(this.timer!==null)this.deps.clearTimer(this.timer);this.timer=null;this.current=null;this.claims=null;this.loaded=null;this.refreshing=null}get storageKey(){return SESSION_STORAGE_PREFIX+(this.audience??"")}subscribe(e){this.listeners.add(e);return()=>this.listeners.delete(e)}notify(){for(const e of[...this.listeners]){try{e()}catch(t){console.warn("[Buoy] sign-in listener error:",t)}}}getAccessToken(){const e=this.getStatus();return e.state==="active"&&!e.grace?this.current?.accessToken??null:null}getStatus(){const e=this.claims;if(!e)return{state:"signed_out"};const t=e.exp*1e3;const i=this.deps.now();if(i<(e.iat-w)*1e3)return{state:"signed_out"};if(i<t)return{state:"active",claims:e,grace:false,validUntil:t};if(i<t+SESSION_OFFLINE_GRACE_MS){return{state:"active",claims:e,grace:true,validUntil:t+SESSION_OFFLINE_GRACE_MS}}return{state:"signed_out"}}load(){if(!this.loaded)this.loaded=this.loadOnce();return this.loaded}async loadOnce(){if(!this.audience)return;this.unwatch??=this.deps.watch?.({storage:t=>{if(t===null||t===this.storageKey)void this.sync()},wake:()=>{if(this.claims)void this.refresh()}})??null;const e=await this.read();if(e&&this.adopt(e)){this.notify();this.schedule()}}async sync(){if(!this.audience)return;const e=await this.read();if(!e){if(this.current)this.clearLocal();return}if(e.refreshToken!==this.current?.refreshToken&&this.adopt(e)){this.notify();this.schedule()}}async read(){try{const e=await(await this.deps.storage()).getItem(this.storageKey);if(!e)return null;const t=JSON.parse(e);return t?.v===1&&typeof t.accessToken==="string"&&typeof t.refreshToken==="string"?t:null}catch{return null}}async write(e){const t=await this.deps.storage();if(e)await t.setItem(this.storageKey,JSON.stringify(e));else await t.removeItem(this.storageKey)}adopt(e){if(!this.audience)return false;const t=g(e.accessToken,{audience:this.audience,ignoreTime:true});const i=t.ok?t.claims:null;if(!i)return false;this.current=e;this.claims=i;return true}armLimit(){if(this.limitTimer!==null)this.deps.clearTimer(this.limitTimer);this.limitTimer=null;if(!this.claims)return;const e=this.claims.exp*1e3;const t=this.deps.now();const i=t<e?e:t<e+SESSION_OFFLINE_GRACE_MS?e+SESSION_OFFLINE_GRACE_MS:null;if(i===null)return;this.limitTimer=this.deps.setTimer(()=>{this.limitTimer=null;this.notify();this.armLimit()},i-t)}call(e,t){return new Promise((i,r)=>{const n=this.deps.setTimer(()=>r(new Error("timeout")),SESSION_CALL_TIMEOUT_MS);this.deps.fetch(e,t).then(s=>{this.deps.clearTimer(n);i(s)},s=>{this.deps.clearTimer(n);r(s)})})}schedule(){this.armLimit();if(this.timer!==null)this.deps.clearTimer(this.timer);this.timer=null;if(!this.claims)return;const e=this.claims.exp*1e3-SESSION_REFRESH_LEAD_MS-this.deps.now();this.timer=this.deps.setTimer(()=>{this.timer=null;void this.refresh()},Math.max(0,e))}refresh(e=false){if(!this.refreshing){this.refreshing=this.deps.withLock(this.lockName,()=>this.refreshLocked(e)).catch(()=>this.retryLater()).finally(()=>{this.refreshing=null})}return this.refreshing}get lockName(){return`buoy-session:${this.audience??""}`}async refreshLocked(e){const t=this.epoch;const i=await this.read();if(!i){if(this.current)this.clearLocal();return}if(i.refreshToken!==this.current?.refreshToken){if(this.adopt(i)){this.notify();this.schedule();return}}if(!this.claims)return;if(!e&&this.claims.exp*1e3-this.deps.now()>SESSION_REFRESH_LEAD_MS){this.schedule();return}let r;let n;try{const s=await this.call(`${this.signinOrigin}/api/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refresh_token:i.refreshToken,audience:this.audience})});r=s.status;n=await s.json().catch(()=>null)}catch{this.retryLater();return}if(t!==this.epoch)return;if(r===200&&n&&typeof n.access_token==="string"&&typeof n.refresh_token==="string"){const s={v:1,accessToken:n.access_token,refreshToken:n.refresh_token};if(this.adopt(s)){await this.write(s);this.notify();this.schedule();return}}if(r===400||r===401||r===403){await this.write(null);this.clearLocal();return}this.retryLater()}retryLater(){this.armLimit();if(this.timer!==null)this.deps.clearTimer(this.timer);this.timer=this.deps.setTimer(()=>{this.timer=null;void this.refresh(true)},SESSION_RETRY_MS);this.notify()}clearLocal(){if(this.timer!==null)this.deps.clearTimer(this.timer);this.timer=null;if(this.limitTimer!==null)this.deps.clearTimer(this.limitTimer);this.limitTimer=null;this.current=null;this.claims=null;this.notify()}async signIn(){if(!this.audience)throw new SessionError("not_configured","Sign-in needs a web page or a configured app id.");const e=this.deps.openPopup();if(!e)throw new SessionError("popup_blocked","The browser blocked the sign-in window. Allow pop-ups for this site and try again.");try{return await this.signInWith((t,i)=>new Promise((r,n)=>{e.location.href=t;const s=this.deps.now();let l=null;const h=u=>{if(l!==null)this.deps.clearTimer(l);a();u()};const a=this.deps.onMessage(u=>{if(u.origin!==this.signinOrigin)return;const d=u.data;if(!d||d.type!==y||d.state!==i)return;if(typeof d.code==="string")h(()=>r(d.code));else h(()=>n(new SessionError("access_denied","Sign-in was cancelled.")))});const c=()=>{if(e.closed)return h(()=>n(new SessionError("popup_closed","The sign-in window was closed.")));if(this.deps.now()-s>T)return h(()=>n(new SessionError("timeout","Sign-in took too long.")));l=this.deps.setTimer(c,500)};l=this.deps.setTimer(c,500)}))}finally{try{if(!e.closed)e.close()}catch{}}}async signInWith(e){const t=this.audience;if(!t)throw new SessionError("not_configured","Sign-in needs a web page or a configured app id.");const i=f(this.deps.random(32));const r=f(this.deps.random(16));const n=f(await this.deps.sha256(new TextEncoder().encode(i)));const s=`${this.signinOrigin}/auth/authorize?audience=${encodeURIComponent(t)}&code_challenge=${n}&code_challenge_method=S256&state=${r}`;const l=await e(s,r);let h;try{h=await this.call(`${this.signinOrigin}/api/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:l,code_verifier:i,audience:t})})}catch{throw new SessionError("network","Buoy could not be reached. Check your connection and try again.")}const a=await h.json().catch(()=>null);if(h.status!==200||!a||typeof a.access_token!=="string"||typeof a.refresh_token!=="string"){const c=a&&typeof a.error_description==="string"?a.error_description:"Buoy did not accept this sign-in.";throw new SessionError(h.status===503?"unavailable":"rejected",c)}return this.finishSignIn(a.access_token,a.refresh_token)}async finishSignIn(e,t){const i={v:1,accessToken:e,refreshToken:t};this.epoch+=1;if(!this.adopt(i))throw new SessionError("rejected","Buoy sent a sign-in this app could not check.");await this.write(i);await this.load();this.notify();this.schedule();return this.getStatus()}async signInWithCode(e,t={}){const i=this.audience;if(!i)throw new SessionError("not_configured","Sign-in with a code needs this app's id (app:com.example.app).");const r=(a,c)=>this.call(`${this.signinOrigin}/api/auth/device/${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(c)});let n;try{n=await r("start",{audience:i})}catch{throw new SessionError("network","Buoy could not be reached. Check your connection and try again.")}const s=await n.json().catch(()=>null);if(n.status!==200||!s||typeof s.device_code!=="string"||typeof s.user_code!=="string"||typeof s.verification_uri!=="string"||typeof s.verification_uri_complete!=="string"){const a=s&&typeof s.error_description==="string"?s.error_description:"Buoy could not start a sign-in.";throw new SessionError(n.status===503?"unavailable":"rejected",a)}const l=this.deps.now()+(Number(s.expires_in)||600)*1e3;let h=Math.max(5,Number(s.interval)||5)*1e3;e({userCode:s.user_code,verificationUri:s.verification_uri,verificationUriComplete:s.verification_uri_complete,expiresAt:l});for(;;){await this.wait(h,t.signal);if(this.deps.now()>l)throw new SessionError("timeout","The code ran out. Start again for a new one.");let a;try{a=await r("poll",{device_code:s.device_code})}catch{continue}const c=await a.json().catch(()=>null);if(a.status===200&&c&&typeof c.access_token==="string"&&typeof c.refresh_token==="string"){return this.finishSignIn(c.access_token,c.refresh_token)}const u=c&&typeof c.error==="string"?c.error:"";if(u==="authorization_pending"||a.status>=500)continue;if(u==="slow_down"||a.status===429){h+=5e3;continue}if(u==="access_denied")throw new SessionError("access_denied","The sign-in was turned down on buoy.gg.");if(u==="expired_token")throw new SessionError("timeout","The code ran out. Start again for a new one.");const d=c&&typeof c.error_description==="string"?c.error_description:"Buoy did not accept this sign-in.";throw new SessionError("rejected",d)}}wait(e,t){return new Promise((i,r)=>{const n=()=>new SessionError("access_denied","Sign-in was cancelled.");if(t?.aborted)return r(n());const s=()=>{this.deps.clearTimer(l);r(n())};const l=this.deps.setTimer(()=>{t?.removeEventListener?.("abort",s);i()},e);t?.addEventListener?.("abort",s)})}async signOut(){this.epoch+=1;const e=this.current;this.clearLocal();let t=e;try{await this.deps.withLock(this.lockName,async()=>{t=await this.read()??e;await this.write(null)})}catch{await this.write(null).catch(()=>{})}if(!t)return;try{await this.call(`${this.signinOrigin}/api/auth/revoke`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refresh_token:t.refreshToken})})}catch{}}}export const SessionManager=new SessionManagerImpl;
|
|
6
|
+
*/import{getLicenseStorage as f}from"./storage";import{base64urlEncode as p,verifySessionToken as g,SESSION_CLOCK_SKEW_SECONDS as m}from"./sessionToken.js";import{realNow as w}from"./realNow.js";export const SESSION_STORAGE_PREFIX="@buoy/session:";export const SESSION_OFFLINE_GRACE_MS=7*24*60*60*1e3;export const SESSION_REFRESH_LEAD_MS=6*60*60*1e3;export const SESSION_PLAN_CHECK_MS=5*60*1e3;export const SESSION_PLAN_RETRY_MS=5*1e3;export const SESSION_RETRY_MS=5*60*1e3;export const SESSION_CALL_TIMEOUT_MS=15e3;export const DEFAULT_SIGNIN_ORIGIN="https://buoy.gg";const y="buoy:signin";const _=10*60*1e3;export class SessionError extends Error{constructor(e,t){super(t);this.code=e;this.name="SessionError"}}function T(){const n=globalThis;return{fetch:(e,t)=>fetch(e,t),storage:f,now:w,random:e=>{const t=new Uint8Array(e);if(!n.crypto?.getRandomValues)throw new SessionError("not_configured","This platform has no secure random source.");return n.crypto.getRandomValues(t)},sha256:async e=>{if(!n.crypto?.subtle)throw new SessionError("not_configured","Sign-in needs a secure page (https or localhost).");return new Uint8Array(await n.crypto.subtle.digest("SHA-256",e))},openPopup:()=>{if(!n.window?.open)return null;const e=480;const t=640;const i=Math.max(0,(n.window.screenX??0)+((n.window.outerWidth??e)-e)/2);const o=Math.max(0,(n.window.screenY??0)+((n.window.outerHeight??t)-t)/2);return n.window.open("about:blank","buoy-signin",`popup,width=${e},height=${t},left=${i},top=${o}`)},onMessage:e=>{if(!n.window?.addEventListener)return()=>{};const t=i=>e({origin:i.origin,data:i.data});n.window.addEventListener("message",t);return()=>n.window?.removeEventListener("message",t)},withLock:(e,t)=>n.navigator?.locks?n.navigator.locks.request(e,t):t(),checksPlan:!n.window?.addEventListener||!!n.navigator?.locks,watch:e=>{const t=n.window;if(!t?.addEventListener)return S(e.wake);const i=c=>e.storage(c.key);const o=()=>{if(t.document?.visibilityState!=="hidden")e.wake()};t.addEventListener("storage",i);t.addEventListener("online",e.wake);t.document?.addEventListener?.("visibilitychange",o);return()=>{t.removeEventListener("storage",i);t.removeEventListener("online",e.wake);t.document?.removeEventListener?.("visibilitychange",o)}},setTimer:(e,t)=>setTimeout(e,Math.min(t,2147483647)),clearTimer:e=>clearTimeout(e)}}function S(n){try{const{AppState:e}=require("react-native");const t=e?.addEventListener?.("change",i=>{if(i==="active")n()});return()=>t?.remove()}catch{return()=>{}}}function k(){const n=globalThis.location;if(!n?.origin||!/^https?:$/.test(n.protocol??""))return void 0;return n.origin}export class SessionManagerImpl{signinOrigin=DEFAULT_SIGNIN_ORIGIN;current=null;claims=null;listeners=new Set;timer=null;refreshing=null;loaded=null;unwatch=null;limitTimer=null;epoch=0;constructor(e){this.deps=e??T();this.audience=k()}get origin(){return this.signinOrigin}configure(e){if(e.audience!==void 0)this.audience=e.audience;if(e.signinOrigin!==void 0)this.signinOrigin=e.signinOrigin.replace(/\/$/,"");this.reset()}reset(){this.planRetries=0;this.unwatch?.();this.unwatch=null;this.epoch+=1;if(this.limitTimer!==null)this.deps.clearTimer(this.limitTimer);this.limitTimer=null;if(this.timer!==null)this.deps.clearTimer(this.timer);this.timer=null;this.current=null;this.claims=null;this.loaded=null;this.refreshing=null}get storageKey(){return SESSION_STORAGE_PREFIX+(this.audience??"")}subscribe(e){this.listeners.add(e);return()=>this.listeners.delete(e)}notify(){for(const e of[...this.listeners]){try{e()}catch(t){console.warn("[Buoy] sign-in listener error:",t)}}}getAccessToken(){const e=this.getStatus();return e.state==="active"&&!e.grace?this.current?.accessToken??null:null}getStatus(){const e=this.claims;if(!e)return{state:"signed_out"};const t=e.exp*1e3;const i=this.deps.now();if(i<(e.iat-m)*1e3)return{state:"signed_out"};if(i<t)return{state:"active",claims:e,grace:false,validUntil:t};if(i<t+SESSION_OFFLINE_GRACE_MS){return{state:"active",claims:e,grace:true,validUntil:t+SESSION_OFFLINE_GRACE_MS}}return{state:"signed_out"}}load(){if(!this.loaded)this.loaded=this.loadOnce();return this.loaded}async loadOnce(){if(!this.audience)return;this.unwatch??=this.deps.watch?.({storage:t=>{if(t===null||t===this.storageKey)void this.sync()},wake:()=>{if(this.deps.checksPlan)void this.checkPlan();else if(this.claims)void this.refresh()}})??null;const e=await this.read();if(e&&this.adopt(e)){this.notify();this.schedule();if(this.deps.checksPlan)void this.checkPlan()}}async sync(){if(!this.audience)return;const e=await this.read();if(!e){if(this.current)this.clearLocal();return}if(e.refreshToken!==this.current?.refreshToken&&this.adopt(e)){this.notify();this.schedule()}}async read(){try{const e=await(await this.deps.storage()).getItem(this.storageKey);if(!e)return null;const t=JSON.parse(e);return t?.v===1&&typeof t.accessToken==="string"&&typeof t.refreshToken==="string"?t:null}catch{return null}}async write(e){const t=await this.deps.storage();if(e)await t.setItem(this.storageKey,JSON.stringify(e));else await t.removeItem(this.storageKey)}adopt(e){if(!this.audience)return false;const t=g(e.accessToken,{audience:this.audience,ignoreTime:true});const i=t.ok?t.claims:null;if(!i)return false;this.current=e;this.claims=i;return true}armLimit(){if(this.limitTimer!==null)this.deps.clearTimer(this.limitTimer);this.limitTimer=null;if(!this.claims)return;const e=this.claims.exp*1e3;const t=this.deps.now();const i=t<e?e:t<e+SESSION_OFFLINE_GRACE_MS?e+SESSION_OFFLINE_GRACE_MS:null;if(i===null)return;this.limitTimer=this.deps.setTimer(()=>{this.limitTimer=null;this.notify();this.armLimit()},i-t)}call(e,t){return new Promise((i,o)=>{const c=this.deps.setTimer(()=>o(new Error("timeout")),SESSION_CALL_TIMEOUT_MS);this.deps.fetch(e,t).then(s=>{this.deps.clearTimer(c);i(s)},s=>{this.deps.clearTimer(c);o(s)})})}schedule(){this.armLimit();if(this.timer!==null)this.deps.clearTimer(this.timer);this.timer=null;if(!this.claims)return;const e=this.claims.exp*1e3-SESSION_REFRESH_LEAD_MS-this.deps.now();this.timer=this.deps.setTimer(()=>{this.timer=null;void this.refresh()},Math.max(0,e))}refresh(e=false){return this.startRefresh(()=>this.refreshLocked(e))}checkPlan(e=SESSION_PLAN_CHECK_MS){return this.startRefresh(()=>this.refreshLocked(false,e))}planRetries=0;retryPlanCheck(){if(this.planRetries>=2){this.planRetries=0;this.schedule();return}this.planRetries+=1;if(this.timer!==null)this.deps.clearTimer(this.timer);this.timer=this.deps.setTimer(()=>{this.timer=null;void this.checkPlan(0)},SESSION_PLAN_RETRY_MS)}startRefresh(e){if(!this.refreshing){this.refreshing=this.deps.withLock(this.lockName,e).catch(()=>this.retryLater()).finally(()=>{this.refreshing=null})}return this.refreshing}get lockName(){return`buoy-session:${this.audience??""}`}async refreshLocked(e,t){const i=this.epoch;const o=await this.read();if(!o){if(this.current)this.clearLocal();return}if(o.refreshToken!==this.current?.refreshToken){if(this.adopt(o)){this.notify();this.schedule();return}}if(!this.claims)return;const c=this.claims.exp*1e3-this.deps.now()>SESSION_REFRESH_LEAD_MS;const s=!e&&c&&t!==void 0;const d=s&&this.planRetries>0&&this.timer===null;const l=s&&this.deps.now()-this.claims.iat*1e3>=t;if(!e&&c&&!l&&!d){if(!this.planRetries)this.schedule();return}const a=()=>s?this.retryPlanCheck():this.retryLater();let r;let h;try{const u=await this.call(`${this.signinOrigin}/api/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refresh_token:o.refreshToken,audience:this.audience})});r=u.status;h=await u.json().catch(()=>null)}catch{if(i===this.epoch)a();return}if(i!==this.epoch)return;if(r===200&&h&&typeof h.access_token==="string"&&typeof h.refresh_token==="string"){const u={v:1,accessToken:h.access_token,refreshToken:h.refresh_token};if(this.adopt(u)){this.planRetries=0;await this.write(u);this.notify();this.schedule();return}}if(r===400||r===401||r===403){await this.write(null);this.clearLocal();return}a()}retryLater(){this.armLimit();if(this.timer!==null)this.deps.clearTimer(this.timer);this.timer=this.deps.setTimer(()=>{this.timer=null;void this.refresh(true)},SESSION_RETRY_MS);this.notify()}clearLocal(){this.planRetries=0;if(this.timer!==null)this.deps.clearTimer(this.timer);this.timer=null;if(this.limitTimer!==null)this.deps.clearTimer(this.limitTimer);this.limitTimer=null;this.current=null;this.claims=null;this.notify()}async signIn(){if(!this.audience)throw new SessionError("not_configured","Sign-in needs a web page or a configured app id.");const e=this.deps.openPopup();if(!e)throw new SessionError("popup_blocked","The browser blocked the sign-in window. Allow pop-ups for this site and try again.");try{return await this.signInWith((t,i)=>new Promise((o,c)=>{e.location.href=t;const s=this.deps.now();let d=null;const l=h=>{if(d!==null)this.deps.clearTimer(d);a();h()};const a=this.deps.onMessage(h=>{if(h.origin!==this.signinOrigin)return;const u=h.data;if(!u||u.type!==y||u.state!==i)return;if(typeof u.code==="string")l(()=>o(u.code));else l(()=>c(new SessionError("access_denied","Sign-in was cancelled.")))});const r=()=>{if(e.closed)return l(()=>c(new SessionError("popup_closed","The sign-in window was closed.")));if(this.deps.now()-s>_)return l(()=>c(new SessionError("timeout","Sign-in took too long.")));d=this.deps.setTimer(r,500)};d=this.deps.setTimer(r,500)}))}finally{try{if(!e.closed)e.close()}catch{}}}async signInWith(e){const t=this.audience;if(!t)throw new SessionError("not_configured","Sign-in needs a web page or a configured app id.");const i=p(this.deps.random(32));const o=p(this.deps.random(16));const c=p(await this.deps.sha256(new TextEncoder().encode(i)));const s=`${this.signinOrigin}/auth/authorize?audience=${encodeURIComponent(t)}&code_challenge=${c}&code_challenge_method=S256&state=${o}`;const d=await e(s,o);let l;try{l=await this.call(`${this.signinOrigin}/api/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:d,code_verifier:i,audience:t})})}catch{throw new SessionError("network","Buoy could not be reached. Check your connection and try again.")}const a=await l.json().catch(()=>null);if(l.status!==200||!a||typeof a.access_token!=="string"||typeof a.refresh_token!=="string"){const r=a&&typeof a.error_description==="string"?a.error_description:"Buoy did not accept this sign-in.";throw new SessionError(l.status===503?"unavailable":"rejected",r)}return this.finishSignIn(a.access_token,a.refresh_token)}async finishSignIn(e,t){const i={v:1,accessToken:e,refreshToken:t};this.epoch+=1;if(!this.adopt(i))throw new SessionError("rejected","Buoy sent a sign-in this app could not check.");await this.write(i);await this.load();this.notify();this.schedule();return this.getStatus()}async signInWithCode(e,t={}){const i=this.audience;if(!i)throw new SessionError("not_configured","Sign-in with a code needs this app's id (app:com.example.app).");const o=(a,r)=>this.call(`${this.signinOrigin}/api/auth/device/${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)});let c;try{c=await o("start",{audience:i})}catch{throw new SessionError("network","Buoy could not be reached. Check your connection and try again.")}const s=await c.json().catch(()=>null);if(c.status!==200||!s||typeof s.device_code!=="string"||typeof s.user_code!=="string"||typeof s.verification_uri!=="string"||typeof s.verification_uri_complete!=="string"){const a=s&&typeof s.error_description==="string"?s.error_description:"Buoy could not start a sign-in.";throw new SessionError(c.status===503?"unavailable":"rejected",a)}const d=this.deps.now()+(Number(s.expires_in)||600)*1e3;let l=Math.max(5,Number(s.interval)||5)*1e3;e({userCode:s.user_code,verificationUri:s.verification_uri,verificationUriComplete:s.verification_uri_complete,expiresAt:d});for(;;){await this.wait(l,t.signal);if(this.deps.now()>d)throw new SessionError("timeout","The code ran out. Start again for a new one.");let a;try{a=await o("poll",{device_code:s.device_code})}catch{continue}const r=await a.json().catch(()=>null);if(a.status===200&&r&&typeof r.access_token==="string"&&typeof r.refresh_token==="string"){return this.finishSignIn(r.access_token,r.refresh_token)}const h=r&&typeof r.error==="string"?r.error:"";if(h==="authorization_pending"||a.status>=500)continue;if(h==="slow_down"||a.status===429){l+=5e3;continue}if(h==="access_denied")throw new SessionError("access_denied","The sign-in was turned down on buoy.gg.");if(h==="expired_token")throw new SessionError("timeout","The code ran out. Start again for a new one.");const u=r&&typeof r.error_description==="string"?r.error_description:"Buoy did not accept this sign-in.";throw new SessionError("rejected",u)}}wait(e,t){return new Promise((i,o)=>{const c=()=>new SessionError("access_denied","Sign-in was cancelled.");if(t?.aborted)return o(c());const s=()=>{this.deps.clearTimer(d);o(c())};const d=this.deps.setTimer(()=>{t?.removeEventListener?.("abort",s);i()},e);t?.addEventListener?.("abort",s)})}async signOut(){this.epoch+=1;const e=this.current;this.clearLocal();let t=e;try{await this.deps.withLock(this.lockName,async()=>{t=await this.read()??e;await this.write(null)})}catch{await this.write(null).catch(()=>{})}if(!t)return;try{await this.call(`${this.signinOrigin}/api/auth/revoke`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refresh_token:t.refreshToken})})}catch{}}}export const SessionManager=new SessionManagerImpl;
|
|
@@ -10,6 +10,19 @@ export declare const SESSION_STORAGE_PREFIX = "@buoy/session:";
|
|
|
10
10
|
export declare const SESSION_OFFLINE_GRACE_MS: number;
|
|
11
11
|
/** Refresh once less than this is left on the access token (they last 12 h). */
|
|
12
12
|
export declare const SESSION_REFRESH_LEAD_MS: number;
|
|
13
|
+
/**
|
|
14
|
+
* Apps ask buoy.gg again once a sign-in is this old, when they start or come
|
|
15
|
+
* back to the front. The plan lives in the token, so without this a person who
|
|
16
|
+
* just paid stays Free until the next refresh, up to 6 hours away.
|
|
17
|
+
*/
|
|
18
|
+
export declare const SESSION_PLAN_CHECK_MS: number;
|
|
19
|
+
/**
|
|
20
|
+
* After a plan check fails, try again this soon, twice at most. If the reply was
|
|
21
|
+
* lost, buoy.gg has spent the token and accepts a retry for only 60 seconds.
|
|
22
|
+
* After that, the same token ends the sign-in. Each try can take 15 seconds to
|
|
23
|
+
* time out, so the last one starts about 40 seconds in.
|
|
24
|
+
*/
|
|
25
|
+
export declare const SESSION_PLAN_RETRY_MS: number;
|
|
13
26
|
/** Retry delay after buoy.gg could not be reached. */
|
|
14
27
|
export declare const SESSION_RETRY_MS: number;
|
|
15
28
|
/** A web call to buoy.gg that takes longer than this counts as offline. */
|
|
@@ -88,6 +101,11 @@ export interface SessionDeps {
|
|
|
88
101
|
storage: (key: string | null) => void;
|
|
89
102
|
wake: () => void;
|
|
90
103
|
}) => () => void;
|
|
104
|
+
/**
|
|
105
|
+
* Also ask for the plan on start and wake (SESSION_PLAN_CHECK_MS). Apps and
|
|
106
|
+
* pages only: a Node host is a short-lived command, and starts often.
|
|
107
|
+
*/
|
|
108
|
+
checksPlan?: boolean;
|
|
91
109
|
}
|
|
92
110
|
export interface SessionConfig {
|
|
93
111
|
/** Origin ("https://app.acme.com") or app id ("app:com.acme.app"). Web default: this page's origin. */
|
|
@@ -155,6 +173,14 @@ export declare class SessionManagerImpl {
|
|
|
155
173
|
* Never throws: failures land in getStatus().
|
|
156
174
|
*/
|
|
157
175
|
refresh(force?: boolean): Promise<void>;
|
|
176
|
+
/**
|
|
177
|
+
* Ask buoy.gg for the current plan once the token is `minAgeMs` old. A failure
|
|
178
|
+
* here stays quiet: the normal refresh still comes when it's due. Never throws.
|
|
179
|
+
*/
|
|
180
|
+
checkPlan(minAgeMs?: number): Promise<void>;
|
|
181
|
+
private planRetries;
|
|
182
|
+
private retryPlanCheck;
|
|
183
|
+
private startRefresh;
|
|
158
184
|
private get lockName();
|
|
159
185
|
private refreshLocked;
|
|
160
186
|
private retryLater;
|
|
@@ -10,6 +10,19 @@ export declare const SESSION_STORAGE_PREFIX = "@buoy/session:";
|
|
|
10
10
|
export declare const SESSION_OFFLINE_GRACE_MS: number;
|
|
11
11
|
/** Refresh once less than this is left on the access token (they last 12 h). */
|
|
12
12
|
export declare const SESSION_REFRESH_LEAD_MS: number;
|
|
13
|
+
/**
|
|
14
|
+
* Apps ask buoy.gg again once a sign-in is this old, when they start or come
|
|
15
|
+
* back to the front. The plan lives in the token, so without this a person who
|
|
16
|
+
* just paid stays Free until the next refresh, up to 6 hours away.
|
|
17
|
+
*/
|
|
18
|
+
export declare const SESSION_PLAN_CHECK_MS: number;
|
|
19
|
+
/**
|
|
20
|
+
* After a plan check fails, try again this soon, twice at most. If the reply was
|
|
21
|
+
* lost, buoy.gg has spent the token and accepts a retry for only 60 seconds.
|
|
22
|
+
* After that, the same token ends the sign-in. Each try can take 15 seconds to
|
|
23
|
+
* time out, so the last one starts about 40 seconds in.
|
|
24
|
+
*/
|
|
25
|
+
export declare const SESSION_PLAN_RETRY_MS: number;
|
|
13
26
|
/** Retry delay after buoy.gg could not be reached. */
|
|
14
27
|
export declare const SESSION_RETRY_MS: number;
|
|
15
28
|
/** A web call to buoy.gg that takes longer than this counts as offline. */
|
|
@@ -88,6 +101,11 @@ export interface SessionDeps {
|
|
|
88
101
|
storage: (key: string | null) => void;
|
|
89
102
|
wake: () => void;
|
|
90
103
|
}) => () => void;
|
|
104
|
+
/**
|
|
105
|
+
* Also ask for the plan on start and wake (SESSION_PLAN_CHECK_MS). Apps and
|
|
106
|
+
* pages only: a Node host is a short-lived command, and starts often.
|
|
107
|
+
*/
|
|
108
|
+
checksPlan?: boolean;
|
|
91
109
|
}
|
|
92
110
|
export interface SessionConfig {
|
|
93
111
|
/** Origin ("https://app.acme.com") or app id ("app:com.acme.app"). Web default: this page's origin. */
|
|
@@ -155,6 +173,14 @@ export declare class SessionManagerImpl {
|
|
|
155
173
|
* Never throws: failures land in getStatus().
|
|
156
174
|
*/
|
|
157
175
|
refresh(force?: boolean): Promise<void>;
|
|
176
|
+
/**
|
|
177
|
+
* Ask buoy.gg for the current plan once the token is `minAgeMs` old. A failure
|
|
178
|
+
* here stays quiet: the normal refresh still comes when it's due. Never throws.
|
|
179
|
+
*/
|
|
180
|
+
checkPlan(minAgeMs?: number): Promise<void>;
|
|
181
|
+
private planRetries;
|
|
182
|
+
private retryPlanCheck;
|
|
183
|
+
private startRefresh;
|
|
158
184
|
private get lockName();
|
|
159
185
|
private refreshLocked;
|
|
160
186
|
private retryLater;
|
package/lib/web/capacitor.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{a,b as t,c as i,d as s,e as c,f as r,g as e,h as l,i as o,j as p,k as C,l as n,m as g,n as m,o as u,p as d,q as b,r as h,s as k}from"./chunks/chunk-
|
|
1
|
+
"use client";import{a,b as t,c as i,d as s,e as c,f as r,g as e,h as l,i as o,j as p,k as C,l as n,m as g,n as m,o as u,p as d,q as b,r as h,s as k}from"./chunks/chunk-KGEZ5TEJ.mjs";import"./chunks/chunk-YHWYXKID.mjs";export{C as callCapacitorAsApp,p as callCapacitorNative,n as callCapacitorNativeCallback,l as capacitorListenerCount,b as capacitorPlugin,u as clearCapacitorCalls,i as colorSchemeQueryValue,e as emitCapacitorEvent,k as getCapacitorAppHost,m as getCapacitorCalls,s as getColorSchemeQueries,o as hasCapacitorPlugin,t as installCapacitorBridge,r as interceptCapacitor,c as isCapacitorBridgeInstalled,g as listenCapacitorNative,h as loadCapacitorAppHost,a as makeCapacitorCallbackId,d as subscribeCapacitorCalls};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{m as e}from"./chunk-U4JDBLRG.mjs";import"./chunk-YHWYXKID.mjs";export{e as LicenseManager};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{f as G,g as R}from"./chunk-YHWYXKID.mjs";G();var $="__BUOY_CAPACITOR_BRIDGE__",x=300;function w(){let e=globalThis.Capacitor;return e&&typeof e=="object"?e:null}function g(){let e=globalThis,t=e[$];return(!t||t.version!==1)&&(t={version:1,originalPromise:null,originalCallback:null,wrappedPromise:null,wrappedCallback:null,interceptors:[],listeners:new Map,log:[],subscribers:new Set,seq:0,fakeIds:0},e[$]=t),t}function k(){let e=globalThis.__buoyRealNow;return typeof e=="function"?e():Date.now()}function W(e){e.clickListenerInstalled||typeof window>"u"||typeof window.addEventListener!="function"||(e.clickListenerInstalled=true,window.addEventListener("click",t=>{let r=t.composedPath?.()[0]??t.target;for(e.buoyClick=false;r;){if(r.closest?.("[data-buoy-root], [data-buoy-portal-host]")){e.buoyClick=true;break}r=r.getRootNode?.().host??null}e.clickTimer&&clearTimeout(e.clickTimer),e.clickTimer=setTimeout(()=>{e.buoyClick=false},0)},true))}function C(e){return e&&typeof e=="object"?e:{}}function V(e,t,r,n){if(t!=="SentryCapacitor"||r!=="addBreadcrumb")return false;let o=C(n);if(o.category==="ui.click")return e.buoyClick===true;if(o.category==="console"&&typeof o.message=="string")return/^\[(?:buoy(?:[^\]]*)?|@buoy-gg\/[^\]]+|RnBetterDevTools|React ?Buoy|RN-BUOY DEBUG|js-top|perf-monitor|impersonate|RenderCause|HighlightUpdates|RenderTracker|ProfilerInterceptor|HighlightPerf|DebugBorders|optional-module|route-events|RouteObserver)\]/i.test(o.message);if(o.category!=="fetch"&&o.category!=="xhr")return false;let i=C(o.data);if(typeof i.url!="string")return false;try{let a=new URL(i.url,typeof location>"u"?"http://localhost":location.href),f=a.hostname.toLowerCase();if(["api.buoy.gg","ai.buoy.gg","gateway.buoy.gg"].includes(f)||f==="keygen.sh"||f.endsWith(".keygen.sh")||["buoy.gg","www.buoy.gg"].includes(f)&&/^\/api\/(license|settings|auth|session|install|t)(?:\/|$)/.test(a.pathname)||a.pathname==="/buoy-assets.json")return true;let l=globalThis.__BUOY_INTERNAL_HOSTS__;return l instanceof Set&&[...l].some(s=>typeof s=="string"&&s.toLowerCase()===a.host.toLowerCase())}catch{return false}}function P(e){for(let t of Array.from(e.subscribers))try{t()}catch{}}function S(e,t){let r={seq:++e.seq,...t};return e.log.push(r),e.log.length>x&&e.log.splice(0,e.log.length-x),P(e),r}function D(e,t,r){return e.interceptors.filter(n=>(n.plugin==="*"||n.plugin===t.plugin)&&(!n.methods||n.methods.includes(t.method))&&typeof n[r]=="function").map((n,o)=>({interceptor:n,index:o})).sort((n,o)=>(o.interceptor.order??0)-(n.interceptor.order??0)||n.index-o.index).map(n=>n.interceptor)}function T(e,t){return`${e}:${String(t)}`}function z(){return`buoy-${++g().fakeIds}`}function Q(e={}){if(!R())return false;let t=w();if(!t||typeof t.nativePromise!="function"||typeof t.nativeCallback!="function")return false;let r=g();if(r.wrappedPromise&&t.nativePromise===r.wrappedPromise&&t.nativeCallback===r.wrappedCallback)return true;if(t.DEBUG!==true&&e.release!==true)return false;r.originalPromise=t.nativePromise,r.originalCallback=t.nativeCallback;let n=r.originalPromise,o=r.originalCallback,i=(l,s,b,v)=>{let p={plugin:l,method:s,options:C(b)},m=D(r,p,"promise"),u=d=>{if(d>=m.length){if(v(),s==="removeAllListeners")for(let y of Array.from(r.listeners.keys()))y.startsWith(`${l}:`)&&r.listeners.delete(y);return n.call(t,l,s,b)}try{return Promise.resolve(m[d].promise(p,()=>u(d+1)))}catch(y){return Promise.reject(y)}};return u(0)};r.runPromise=i;let a=(l,s,b)=>{if(V(r,l,s,b))return i(l,s,b,()=>{});let v=S(r,{plugin:l,method:s,kind:"promise",options:C(b),start:k()}),p=false,m=i(l,s,b,()=>{p=true});return m.then(u=>{Object.assign(v,{end:k(),ok:true,result:u,answeredByBuoy:!p}),P(r)},u=>{Object.assign(v,{end:k(),ok:false,error:u,answeredByBuoy:!p}),P(r)}),m},f=(l,s,b,v)=>{let p=b,m=v;typeof p=="function"&&(m=p,p=null);let u={plugin:l,method:s,options:C(p)},d=S(r,{plugin:l,method:s,kind:"callback",options:u.options,start:k(),events:0}),y=false,A=D(r,u,"callback"),j=(h,c)=>h>=A.length?(y=true,o.call(t,l,s,p,c)):A[h].callback(u,c,_=>j(h+1,_)),U=s==="addListener",O=j(0,(h,c)=>{if(d.events=(d.events??0)+1,!U&&d.end===void 0)d.end=k(),d.ok=!c,c?d.error=c:d.result=h,P(r);else{let _=k();S(r,{plugin:l,method:U?String(u.options.eventName??"event"):s,kind:"event",options:{},start:_,end:_,ok:!c,...c?{error:c}:{result:h}})}m?.(h,c)});if(d.answeredByBuoy=!y,s==="addListener"&&O!=null&&typeof m=="function"){let h=T(l,u.options.eventName),c=r.listeners.get(h);c||r.listeners.set(h,c=new Map),c.set(String(O),m)}else s==="removeListener"&&r.listeners.get(T(l,u.options.eventName))?.delete(String(u.options.callbackId));return O};return t.nativePromise=a,t.nativeCallback=f,r.wrappedPromise=a,r.wrappedCallback=f,W(r),K(),true}var J=/^\s*\(\s*prefers-color-scheme\s*:\s*(dark|light)\s*\)\s*$/i,I="__BUOY_COLOR_SCHEME_QUERIES__";function H(e){let t=J.exec(e);return t?t[1].toLowerCase():null}function K(){let e=globalThis,t=globalThis.WeakRef;if(e[I]||typeof e.matchMedia!="function"||!t)return;let r=[];e[I]=r;let n=e.matchMedia;e.matchMedia=function(o){let i=n.call(this??globalThis,o);if(i&&H(String(o))){for(let a=r.length-1;a>=0;a--)r[a].deref()||r.splice(a,1);r.push(new t(i))}return i}}function Z(){let e=globalThis[I];return e?e.map(t=>t.deref()).filter(t=>!!t):[]}function M(){let e=w(),t=g();return!!(t.wrappedPromise&&e?.nativePromise===t.wrappedPromise)}function F(e){let t=g();return t.interceptors.push(e),()=>{let r=t.interceptors.indexOf(e);r>=0&&t.interceptors.splice(r,1)}}function X(e,t,r){let n=g().listeners.get(T(e,t));if(!n)return 0;let o=0;for(let i of Array.from(n.values()))try{i(r),o++}catch(a){globalThis.console?.error(a)}return o}function ee(e,t){return g().listeners.get(T(e,t))?.size??0}function Y(e){return w()?.PluginHeaders?.find(t=>t.name===e)}function N(e){if(!R())return false;try{return!!Y(e)||w()?.isPluginAvailable?.(e)===true}catch{return false}}function E(){let e=w(),t=g();return{cap:e,promise:t.originalPromise??e?.nativePromise??null,callback:t.originalCallback??e?.nativeCallback??null}}function L(e,t,r={}){let{cap:n,promise:o}=E();return!n||!o?Promise.reject(new Error("Capacitor bridge unavailable")):o.call(n,e,t,r)}function te(e,t,r={}){let n=g().runPromise;return n&&M()?n(e,t,r,()=>{}):L(e,t,r)}function re(e,t,r,n){let{cap:o,callback:i}=E();return!o||!i?null:i.call(o,e,t,r,n)}function q(e,t,r){let{cap:n,promise:o,callback:i}=E();if(!n||!i)return Promise.reject(new Error("Capacitor bridge unavailable"));let a=i.call(n,e,"addListener",{eventName:t},l=>r(l)),f=async()=>{if(a==null)return;let l={eventName:t,callbackId:a};Y(e)?.methods?.find(s=>s.name==="removeListener")?.rtype==="promise"&&o?await o.call(n,e,"removeListener",l):i.call(n,e,"removeListener",l,()=>{})};return Promise.resolve({remove:f})}function ne(){return g().log}function oe(){let e=g();e.log.length=0,P(e)}function ie(e){let t=g();return t.subscribers.add(e),()=>{t.subscribers.delete(e)}}var le=new Set(["then","catch","finally","$$typeof","toJSON","constructor"]);function ae(e){return N(e)?new Proxy({},{get(t,r){if(!(typeof r!="string"||le.has(r)))return r==="addListener"?(n,o)=>q(e,n,o):n=>L(e,r,n??{})}}):null}var B="__BUOY_CAPACITOR_HOST__";function se(){if(!R())return Promise.resolve(null);let e=globalThis,t=e[B];if(t)return t;let r=i=>typeof i=="string"&&i?i:null,n=async i=>{if(!N(i))return{};try{return await L(i,"getInfo")??{}}catch{return{}}},o=Promise.all([n("App"),n("Device")]).then(([i,a])=>{let f={isSimulator:typeof a.isVirtual=="boolean"?a.isVirtual:null,deviceName:r(a.name),bundleId:r(i.id),appName:r(i.name)};return e[`${B}_value`]=f,f});return e[B]=o,o}function ue(){return globalThis[`${B}_value`]??null}export{z as a,Q as b,H as c,Z as d,M as e,F as f,X as g,ee as h,N as i,L as j,te as k,re as l,q as m,ne as n,oe as o,ie as p,ae as q,se as r,ue as s};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use client";import{a as j,b as st,c as at,d as ot,e as m,f,i as lt}from"./chunk-YHWYXKID.mjs";var de,ct=j(()=>{"use strict";f();de='-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif'});import{useEffect as ht,useState as dt}from"react";import{createPortal as ut}from"react-dom";import{jsx as ft}from"react/jsx-runtime";function ue(){let e=document;if(e[S])return e[S].host;let t=document.createElement("div");t.dataset.buoyPortalHost="",Object.assign(t.style,{position:"fixed",inset:"0",zIndex:"2147483647",pointerEvents:"none",fontFamily:de});let i=()=>{let o=document.fullscreenElement,d=o&&o.tagName!=="CANVAS"?o:document.body;t.parentElement!==d&&d.appendChild(t)},r=new Map,n=o=>{(!t.contains(o.target)||!H(o.target))&&r.set(o.code||o.key,{key:o.key,code:o.code,location:o.location,keyCode:o.keyCode,which:o.which,altKey:o.altKey,ctrlKey:o.ctrlKey,metaKey:o.metaKey,shiftKey:o.shiftKey})},s=o=>{r.delete(o.code||o.key)},h=()=>r.clear(),c=()=>{let o=[...r.values()];r.clear();for(let d of o)document.dispatchEvent(new KeyboardEvent("keyup",{...d,bubbles:true}))},a=o=>{H(o.target)&&o.stopPropagation()},l=o=>o.stopPropagation();return i(),document.addEventListener("fullscreenchange",i),document.addEventListener("keydown",n,true),document.addEventListener("keyup",s,true),window.addEventListener("blur",h),t.addEventListener("focusin",c),t.addEventListener("keydown",a),t.addEventListener("keyup",a),t.addEventListener("keypress",a),t.addEventListener("wheel",l,{passive:true}),e[S]={host:t,users:0,dispose:()=>{document.removeEventListener("fullscreenchange",i),document.removeEventListener("keydown",n,true),document.removeEventListener("keyup",s,true),window.removeEventListener("blur",h),t.remove(),delete e[S]}},t}function pt({children:e}){let[t,i]=dt(null);return ht(()=>{let r=ue(),n=document[S];return n.users++,i(r),()=>{--n.users===0&&n.dispose()}},[]),t?ut(ft("div",{"data-buoy-root":"",style:{display:"contents",pointerEvents:"auto"},children:e}),t):null}var S,H,mt=j(()=>{"use strict";f();ct();S=Symbol.for("@buoy-gg/portal-host"),H=e=>{if(!(e instanceof Element))return false;if(e.closest("input, textarea, select"))return true;let t=e.closest("[contenteditable]")?.getAttribute("contenteditable")?.toLowerCase();return t===""||t==="true"||t==="plaintext-only"}});var z={};st(z,{AccessibilityInfo:()=>vt,ActivityIndicator:()=>Le,Alert:()=>Re,Animated:()=>we,AppRegistry:()=>Tt,AppState:()=>At,Appearance:()=>bt,BackHandler:()=>kt,Button:()=>Se,CheckBox:()=>$t,Clipboard:()=>Et,DeviceEventEmitter:()=>ti,Dimensions:()=>xt,Easing:()=>_t,FlatList:()=>Ut,I18nManager:()=>Lt,Image:()=>Ft,ImageBackground:()=>Bt,InteractionManager:()=>It,Keyboard:()=>St,KeyboardAvoidingView:()=>jt,LayoutAnimation:()=>Rt,Linking:()=>Ct,LogBox:()=>ei,Modal:()=>xe,NativeEventEmitter:()=>Pt,NativeModules:()=>wt,PanResponder:()=>Nt,Picker:()=>Ht,PixelRatio:()=>Kt,Platform:()=>Ot,Pressable:()=>ke,ProgressBar:()=>zt,RefreshControl:()=>Gt,SafeAreaView:()=>Yt,ScrollView:()=>Ee,SectionList:()=>Wt,Share:()=>Mt,StatusBar:()=>Jt,StyleSheet:()=>ye,Switch:()=>_e,Text:()=>J,TextInput:()=>ve,Touchable:()=>Xt,TouchableHighlight:()=>Te,TouchableNativeFeedback:()=>qt,TouchableOpacity:()=>be,TouchableWithoutFeedback:()=>Ae,UIManager:()=>Vt,Vibration:()=>Dt,View:()=>W,VirtualizedList:()=>Zt,YellowBox:()=>Qt,findNodeHandle:()=>Ie,unstable_createElement:()=>yt,useColorScheme:()=>ii,useLocaleContext:()=>ri,useWindowDimensions:()=>ni});import*as gt from"react-native-web";import{unstable_createElement as yt,NativeModules as wt,AccessibilityInfo as vt,Appearance as bt,AppRegistry as Tt,AppState as At,BackHandler as kt,Clipboard as Et,Dimensions as xt,Easing as _t,I18nManager as Lt,Keyboard as St,InteractionManager as It,LayoutAnimation as Rt,Linking as Ct,NativeEventEmitter as Pt,PanResponder as Nt,PixelRatio as Kt,Platform as Ot,Share as Mt,UIManager as Vt,Vibration as Dt,CheckBox as $t,FlatList as Ut,Image as Ft,ImageBackground as Bt,KeyboardAvoidingView as jt,Picker as Ht,ProgressBar as zt,RefreshControl as Gt,SafeAreaView as Yt,SectionList as Wt,StatusBar as Jt,Touchable as Xt,TouchableNativeFeedback as qt,VirtualizedList as Zt,YellowBox as Qt,LogBox as ei,DeviceEventEmitter as ti,useColorScheme as ii,useLocaleContext as ri,useWindowDimensions as ni}from"react-native-web";import*as g from"react-native-web";import{createElement as G,forwardRef as fe,useCallback as si,useRef as ai}from"react";function Y(e){if(Array.isArray(e)){let d=e.map(Y);return d.some((A,k)=>A!==e[k])?d:e}if(!e||typeof e!="object"||!me.some(d=>e[d]!=null))return e;let{shadowColor:t,shadowOffset:i,shadowOpacity:r,shadowRadius:n,textShadowColor:s,textShadowOffset:h,textShadowRadius:c,...a}=e;if(t!=null||i!=null||r!=null||n!=null){let d=t??"black",A=r==null?d:`color-mix(in srgb, ${d} ${Math.min(r,1)*100}%, transparent)`,k=`${x(i?.width??0)} ${x(i?.height??0)} ${x(n??0)} ${A}`;a.boxShadow=typeof a.boxShadow=="string"?`${a.boxShadow}, ${k}`:a.boxShadow??k}let{width:l=0,height:o=0}=h??{};if(s&&(l||o||c)){let d=`${x(l)} ${x(o)} ${x(c??0)} ${s}`;a.textShadow=a.textShadow?`${a.textShadow}, ${d}`:d}return a}function pe(e,t){if(typeof e=="function")return r=>pe(e(r),t);let i=Y(e);return t?[i,ge[t]]:i}function y(e){let t=fe((r,n)=>{let{accessibilityState:s,accessibilityValue:h,pointerEvents:c,...a}=r;for(let o of["busy","checked","disabled","expanded","selected"])s?.[o]!==void 0&&a[`aria-${o}`]===void 0&&(a[`aria-${o}`]=s[o]);for(let[o,d]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))h?.[o]!==void 0&&a[`aria-${d}`]===void 0&&(a[`aria-${d}`]=h[o]);let l=pe(a.style,c);return l!==a.style&&(a.style=l),G(e,{...a,ref:n})}),i=e.State;return i&&Object.assign(t,{State:i}),t.displayName=e.displayName??e.name??"NativeWebView",t}var E,me,x,ge,ye,W,J,we,ve,be,Te,Ae,ke,Ee,X,xe,_e,Le,Se,Ie,Re,oi=j(()=>{f();at(z,gt);mt();E=g,me=["shadowColor","shadowOffset","shadowOpacity","shadowRadius","textShadowColor","textShadowOffset","textShadowRadius"],x=e=>typeof e=="number"?`${e}px`:e;ge=E.StyleSheet.create({auto:{pointerEvents:"auto"},none:{pointerEvents:"none"},"box-none":{pointerEvents:"box-none"},"box-only":{pointerEvents:"box-only"}});ye={...E.StyleSheet,create:e=>E.StyleSheet.create(Object.fromEntries(Object.entries(e).map(([t,i])=>[t,Y(i)])))};W=y(g.View),J=y(g.Text),we={...E.Animated,View:E.Animated.createAnimatedComponent(W),Text:E.Animated.createAnimatedComponent(J)},ve=y(g.TextInput),be=y(g.TouchableOpacity),Te=y(g.TouchableHighlight),Ae=y(g.TouchableWithoutFeedback),ke=y(g.Pressable),Ee=y(g.ScrollView),X=fe((e,t)=>{let i=ai(null),r=si(n=>{if(n){let s=n;for(;s.parentElement&&s.parentElement!==document.body;)s=s.parentElement;s.parentElement===document.body&&(i.current=s,Object.assign(s.style,{position:"relative",zIndex:"2147483647",pointerEvents:"auto"}),ue().appendChild(s))}else i.current&&(document.body.appendChild(i.current),i.current=null);typeof t=="function"?t(n):t&&(t.current=n)},[t]);return G(pt,null,G(g.Modal,{...e,ref:r}))});X.displayName="Modal";xe=y(X),_e=y(g.Switch),Le=y(g.ActivityIndicator),Se=y(g.Button),Ie=g.findNodeHandle,Re={alert(e,t,i,r){if(typeof document>"u")return;let n=document.createElement("dialog");n.dataset.buoyRoot="",n.setAttribute("aria-label",e),n.style.cssText="position:fixed;inset:0;margin:auto;width:min(440px,90vw);padding:24px;border:1px solid #475569;border-radius:14px;background:#17212e;color:#f1f5f9;font:14px system-ui;box-shadow:0 20px 80px #0008;z-index:2147483647";let s=document.createElement("h2");if(s.textContent=e,s.style.cssText="font-size:18px;margin:0 0 12px",n.appendChild(s),t){let l=document.createElement("p");l.textContent=t,l.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",n.appendChild(l)}let h=document.createElement("div");h.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let c=i?.length?i:[{text:"OK"}],a=()=>{n.close?.(),n.remove()};for(let l of c){let o=document.createElement("button");o.type="button",o.textContent=l.text??"OK",o.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${l.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,o.onclick=()=>{a(),l.onPress?.()},h.appendChild(o)}n.addEventListener("cancel",l=>{l.preventDefault(),r?.cancelable!==false&&(a(),r?.onDismiss?.())}),n.appendChild(h),document.body.appendChild(n),n.showModal?n.showModal():n.setAttribute("open","")}}});f();f();var O=new Map,li={async getItem(e){try{return localStorage.getItem(e)??O.get(e)??null}catch{return O.get(e)??null}},async setItem(e,t){O.set(e,t);try{localStorage.setItem(e,t)}catch{}},async removeItem(e){O.delete(e);try{localStorage.removeItem(e)}catch{}}};async function T(){return li}f();f();var ci="3b546fc717a62683f3236c70167899a271bee3ffc04df6ec1eea60a394a2f1e9";f();var hi="36abba0267f7f379d992a5b6df641daab4190bcc9e639e36f1378e3c1ac52746";var M=Object.freeze({accountId:"b0eba0e8-e904-4906-b644-38f9aab57bed",productId:"bf67cb43-eeef-40ca-b308-e6e1b22c0eaa",apiUrl:"https://buoy.gg/api/license"}),V=Object.freeze({free:"394e3351-1249-4f73-807a-703408604c0e",solo:"fa5d3c8f-5379-40f1-b63e-ab8a974b2f28",business:"690c2212-8e54-426f-b4b4-002ee1c0ae2b"}),D=720*60*60*1e3,di=1440*60*1e3,q="buoy-gg-license",Z="buoy-gg-device-fingerprint",Ce="buoy-gg-device-fingerprint-owner",ui=3600*1e3,fi=[5*1e3,20*1e3,60*1e3,300*1e3,900*1e3],pi=60*1e3,Pe=3600*1e3,mi=1440*60*1e3,gi=50,yi=D,Q="buoy-gg-license-hold";f();f();function u(){let e=globalThis.__buoyRealNow;return typeof e=="function"?e():Date.now()}var{apiUrl:Ne}=M,I=class extends Error{constructor(e,t,i=null){super(e);this.isTransient=true;this.name="LicenseTransportError",this.status=t,this.retryAfterMs=i}};function wi(e){let t=e?.status;return t===429||t===402}function vi(e,t,i){return e.status===402?t:e.retryAfterMs??i}function bi(e){let t=n=>{try{return e.headers?.get?.(n)??null}catch{return null}},i=t("Retry-After");if(i){let n=Number(i);if(Number.isFinite(n)&&n>=0)return n*1e3;let s=Date.parse(i);if(Number.isFinite(s))return Math.max(0,s-u())}let r=Number(t("X-RateLimit-Reset"));return Number.isFinite(r)&&r>0?Math.max(0,r*1e3-u()):null}function Ke(e){return e instanceof I||e instanceof TypeError?true:typeof e=="object"&&e!==null&&e.isTransient===true}async function Ti(e){try{return(await e.json()).errors?.[0]?.detail||`HTTP ${e.status}`}catch{return`HTTP ${e.status}`}}function Oe(){return{"Content-Type":"application/vnd.api+json",Accept:"application/vnd.api+json"}}async function Ai(e,t){let i=`${Ne}/validate`,r={meta:{key:e}},n;try{n=await fetch(i,{signal:t,method:"POST",headers:Oe(),body:JSON.stringify(r)})}catch(s){throw new I(s instanceof Error?s.message:"Network request failed",null)}if(!n.ok)throw new I(await Ti(n),n.status,n.status===429?bi(n):null);try{let s=await n.json();if(!s||typeof s!="object"||typeof s.meta?.valid!="boolean"||typeof s.meta?.code!="string"||!s.meta.code)throw new Error("Missing license verdict");return s}catch{throw new I("License server returned an unreadable response",n.status)}}async function ki(e){let t=typeof AbortController=="function"?new AbortController:null,i;try{return await Promise.race([Ai(e,t?.signal),new Promise((r,n)=>{i=setTimeout(()=>{n(new I("License verification timed out. Please retry.",null)),t?.abort()},15e3)})])}finally{i&&clearTimeout(i)}}function Ei(e){if(!e.data)return false;let t=e.data.relationships?.product?.data?.id;return t&&t!==M.productId?false:e.meta.valid&&e.meta.code==="VALID"?true:["OVERDUE","NO_MACHINE","NO_MACHINES","TOO_MANY_MACHINES","TOO_MANY_CORES","TOO_MANY_PROCESSES","FINGERPRINT_SCOPE_MISMATCH","HEARTBEAT_NOT_STARTED","HEARTBEAT_DEAD"].includes(e.meta.code)}function xi(e){let t=e.data?.relationships?.machines?.meta?.count;return typeof t=="number"&&Number.isFinite(t)?t:0}async function Me(e,t,i,r,n){let s=`${Ne}/machines`,h=await fetch(s,{method:"POST",headers:Oe(),body:JSON.stringify({licenseId:e,licenseKey:t,fingerprint:i,name:r,metadata:n||{}})});if(!h.ok){let c=await h.json(),a=c.errors?.[0]?.code;if(a==="FINGERPRINT_TAKEN")throw new Error("FINGERPRINT_TAKEN");if(a==="MACHINE_LIMIT_EXCEEDED")throw new Error("MACHINE_LIMIT_EXCEEDED");let l=c.errors?.[0]?.detail||`HTTP ${h.status}`;throw new Error(l)}return h.json()}function _i(e){let{meta:t,data:i}=e;return{valid:t.valid,code:t.code,detail:t.detail,metadata:i?.attributes?.metadata}}function Li(e){return["NOT_FOUND","SUSPENDED","EXPIRED","BANNED","PRODUCT_SCOPE_MISMATCH"].includes(e)}f();f();function ee(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}function te(){let e=lt();if(e!==null)return e;if(typeof m<"u")return m;try{if(typeof navigator<"u"&&/electron/i.test(navigator.userAgent))return true}catch{}return typeof process<"u"&&process.env.NODE_ENV!=="production"}function Ve(){if(typeof navigator>"u")return"unknown";let e=navigator.userAgent.toLowerCase(),t=navigator.platform?.toLowerCase()||"";return e.includes("electron")?t.includes("mac")||e.includes("mac")?"electron-macos":t.includes("win")||e.includes("win")?"electron-windows":t.includes("linux")||e.includes("linux")?"electron-linux":"electron":t.includes("mac")||e.includes("mac")?"macos":t.includes("win")||e.includes("win")?"windows":t.includes("linux")||e.includes("linux")?"linux":/iphone|ipad|ipod/.test(e)?"ios-web":e.includes("android")?"android-web":"web"}function Si(){if(typeof navigator>"u")return"unknown";let e=navigator.userAgent,t=e.match(/Mac OS X ([\d_.]+)/);if(t)return t[1].replace(/_/g,".");let i=e.match(/Windows NT ([\d.]+)/);return i?{"10.0":"10/11","6.3":"8.1","6.2":"8","6.1":"7"}[i[1]]||i[1]:e.includes("Linux")?"Linux":"unknown"}function De(){if(typeof navigator>"u")return{name:"unknown",version:"unknown"};let e=navigator.userAgent,t=e.match(/Electron\/([\d.]+)/);if(t)return{name:"Electron",version:t[1]};let i=e.match(/Chrome\/([\d.]+)/);if(i&&!e.includes("Edg"))return{name:"Chrome",version:i[1]};let r=e.match(/Edg\/([\d.]+)/);if(r)return{name:"Edge",version:r[1]};let n=e.match(/Firefox\/([\d.]+)/);if(n)return{name:"Firefox",version:n[1]};let s=e.match(/Version\/([\d.]+).*Safari/);return s?{name:"Safari",version:s[1]}:{name:"unknown",version:"unknown"}}function $e(){let e={platform:Ve(),osVersion:Si(),isSimulator:"false"},t=De();e.browser=t.name,e.browserVersion=t.version,typeof window<"u"&&window.screen&&(e.screenResolution=`${window.screen.width}x${window.screen.height}`),typeof navigator<"u"&&navigator.language&&(e.language=navigator.language);try{e.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone}catch{}return e}function ie(){let e=Ve(),t=De();if(e.startsWith("electron")){let i=e.replace("electron-","").replace("electron","Desktop");return`${i.charAt(0).toUpperCase()+i.slice(1)} App`}return t.name!=="unknown"?`${t.name} Browser`:"Web Browser"}async function Ii(){return null}f();function Ri(e){let{stored:t,storedOwner:i,marker:r,blobFingerprint:n,mint:s}=e;if(!!r&&!!i&&i!==r)return{fingerprint:s(),owner:r,restored:true,changed:true};let h=r??i;return t?{fingerprint:t,owner:h,restored:false,changed:h!==i}:{fingerprint:n||s(),owner:h,restored:false,changed:true}}function Ci(e){let t=2166136261,i=16777619;for(let r=0;r<e.length;r++){let n=e.charCodeAt(r);t=Math.imul(t^n,16777619)>>>0,i=Math.imul(i^n,1540483477)>>>0}return`v1:${t.toString(16).padStart(8,"0")}${i.toString(16).padStart(8,"0")}`}f();var Pi=["v1"],Ni="buoy.gg/pro:9f3c1d7a4b2e:license-cache";function Ue(e,t){let i=t>>>0;for(let r=0;r<e.length;r++)i^=e.charCodeAt(r),i=Math.imul(i,16777619)>>>0;return i>>>0}function Ki(e,t){let i=[t,e.licenseKey,e.licenseId,e.isPro?"1":"0",e.expiresAt??"",String(e.cachedAt)];return t!=="v1"&&i.push(e.tier??""),i.push(Ni),i.join("\0")}function Fe(e,t){let i=Ki(e,t),r=Ue(i,2166136261),n=Ue(i,2135587861);return`${t}.${r.toString(16)}${n.toString(16)}`}function Be(e){return Fe(e,"v2")}function je(e){return{...e,sig:Be(e)}}function R(e){return!e||typeof e.sig!="string"||e.sig.length===0?false:e.sig===Be(e)?true:Pi.some(t=>e.sig.startsWith(`${t}.`)&&e.sig===Fe(e,t))}f();import Oi from"tweetnacl";var Mi=1,Vi=1,Di="buoy-free-token-v1:",$i=22,Ui=64,He=/^BUOY1-([A-Z2-7]+)-([A-Z2-7]+)$/;function ze(e){return He.test(e.trim().toUpperCase())}var Fi="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";function Ge(e){let t=[],i=0,r=0;for(let n of e){let s=Fi.indexOf(n);if(s===-1)return null;r=r<<5|s,i+=5,i>=8&&(t.push(r>>>i-8&255),i-=8)}return new Uint8Array(t)}function Bi(e){let t=e.trim().toLowerCase(),i=new Uint8Array(t.length/2);for(let r=0;r<i.length;r+=1)i[r]=parseInt(t.slice(r*2,r*2+2),16);return i}function ji(e){let t="";for(let i of e)t+=i.toString(16).padStart(2,"0");return t}function Hi(e){if(typeof TextEncoder<"u")return new TextEncoder().encode(e);let t=new Uint8Array(e.length);for(let i=0;i<e.length;i+=1)t[i]=e.charCodeAt(i)&255;return t}function zi(e,t){let i=new Uint8Array(e.length+t.length);return i.set(e,0),i.set(t,e.length),i}function Gi(e){return zi(Hi(Di),e)}var Yi=ci;function Wi(e){let t=He.exec(e.trim().toUpperCase());if(!t)return null;let i=Ge(t[1]),r=Ge(t[2]);if(!i||!r||i.length!==$i||r.length!==Ui||i[0]!==Mi||i[1]!==Vi)return null;try{if(!Oi.sign.detached.verify(Gi(i),r,Bi(Yi)))return null}catch{return null}return{tier:"free",issuedAt:((i[2]<<24>>>0)+(i[3]<<16)+(i[4]<<8)+i[5])*1e3,accountHash:ji(i.slice(6,22))}}f();function Ji(e){let t=e.relationships?.policy?.data?.id;return t===V.free?"free":t===V.solo||t===V.business?"pro":e.attributes?.metadata?.plan==="free"?"free":"pro"}function Xi(e){if(!e)return false;let t=e.relationships?.product?.data?.id;if(t)return t===M.productId;let i=e.relationships?.policy?.data?.id;return Object.values(V).some(r=>r===i)}f();function Ye(e,t=u()){let i=e.verifiedAt!==null&&Number.isFinite(e.verifiedAt)&&e.verifiedAt<=t?e.verifiedAt+D:null;return e.initialized&&e.key&&e.tierSource!=="none"&&i!==null&&t<i?{status:"admitted",reason:null,validUntil:i}:i!==null&&t>=i?{status:"locked",reason:"verification_expired",validUntil:i}:!e.initialized||e.validating?{status:"initializing",reason:"checking",validUntil:i}:{status:"locked",reason:i!==null&&t>=i?"verification_expired":"account_required",validUntil:i}}f();function qi(e){if(typeof window>"u"||typeof window.addEventListener!="function")return()=>{};let t=()=>{document.hidden||e()};return window.addEventListener("focus",e),document.addEventListener("visibilitychange",t),()=>{window.removeEventListener("focus",e),document.removeEventListener("visibilitychange",t)}}f();f();import Zi from"tweetnacl";var We="buoys1",Qi="buoy-session-v1:",Je=1,re=60,er=64,tr=["free","pro","business"],v="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";function ne(e){let t="",i=0;for(;i+2<e.length;i+=3){let n=e[i]<<16|e[i+1]<<8|e[i+2];t+=v[n>>>18&63]+v[n>>>12&63]+v[n>>>6&63]+v[n&63]}let r=e.length-i;if(r===1){let n=e[i]<<16;t+=v[n>>>18&63]+v[n>>>12&63]}else if(r===2){let n=e[i]<<16|e[i+1]<<8;t+=v[n>>>18&63]+v[n>>>12&63]+v[n>>>6&63]}return t}function Xe(e){if(!/^[A-Za-z0-9_-]*$/.test(e)||e.length%4===1)return null;let t=[],i=0,r=0;for(let n of e)r=r<<6|v.indexOf(n),i+=6,i>=8&&(t.push(r>>>i-8&255),i-=8);return new Uint8Array(t)}function ir(e){if(typeof TextEncoder<"u")return new TextEncoder().encode(e);let t=unescape(encodeURIComponent(e)),i=new Uint8Array(t.length);for(let r=0;r<t.length;r+=1)i[r]=t.charCodeAt(r);return i}function rr(e){try{if(typeof TextDecoder<"u")return new TextDecoder("utf-8",{fatal:true}).decode(e);let t="";for(let i of e)t+=String.fromCharCode(i);return decodeURIComponent(escape(t))}catch{return null}}function nr(e){let t=e.trim().toLowerCase(),i=new Uint8Array(t.length/2);for(let r=0;r<i.length;r+=1)i[r]=parseInt(t.slice(r*2,r*2+2),16);return i}function sr(e){return ir(Qi+e)}function C(e,t=256){return typeof e=="string"&&e.length>0&&e.length<=t}function qe(e){return typeof e=="number"&&Number.isInteger(e)&&e>0}function ar(e){if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e;return!C(t.sid)||!C(t.sub)||!C(t.aud,512)||t.team!==null&&!C(t.team)||!tr.includes(t.tier)||t.role!==void 0&&!C(t.role,64)||t.tools!==void 0&&(!Array.isArray(t.tools)||t.tools.length>256||!t.tools.every(i=>C(i,64)))||!qe(t.iat)||!qe(t.exp)||t.exp<=t.iat?null:{v:Je,sid:t.sid,sub:t.sub,team:t.team,tier:t.tier,...t.role!==void 0?{role:t.role}:{},...t.tools!==void 0?{tools:[...t.tools]}:{},aud:t.aud,iat:t.iat,exp:t.exp}}var or=hi;function Ze(e){return e.startsWith(`${We}.`)}function se(e,t){let i=or;if(!i)return{ok:false,reason:"no-key"};let r=typeof e=="string"?e.split("."):[];if(r.length!==3||r[0]!==We)return{ok:false,reason:"malformed"};let[,n,s]=r,h=Xe(n),c=Xe(s);if(!h||!c||c.length!==er)return{ok:false,reason:"malformed"};try{if(!Zi.sign.detached.verify(sr(n),c,nr(i)))return{ok:false,reason:"signature"}}catch{return{ok:false,reason:"signature"}}let a=rr(h),l;try{l=a===null?null:JSON.parse(a)}catch{return{ok:false,reason:"malformed"}}if(!l||typeof l!="object"||l.v!==Je)return{ok:false,reason:l&&typeof l=="object"?"version":"malformed"};let o=ar(l);if(!o)return{ok:false,reason:"claims"};if(o.aud!==t.audience)return{ok:false,reason:"audience"};if(t.ignoreTime)return{ok:true,claims:o};let d=Math.floor((t.nowMs??u())/1e3);return d>=o.exp+re?{ok:false,reason:"expired"}:o.iat>d+re?{ok:false,reason:"not-yet-valid"}:{ok:true,claims:o}}var lr="@buoy/session:",$=10080*60*1e3,Qe=360*60*1e3,cr=300*1e3,hr=5*1e3,dr=300*1e3,ur=15e3,fr="https://buoy.gg",pr="buoy:signin",mr=600*1e3,p=class extends Error{constructor(e,t){super(t);this.code=e;this.name="SessionError"}};function gr(){let e=globalThis;return{fetch:(t,i)=>fetch(t,i),storage:T,now:u,random:t=>{let i=new Uint8Array(t);if(!e.crypto?.getRandomValues)throw new p("not_configured","This platform has no secure random source.");return e.crypto.getRandomValues(i)},sha256:async t=>{if(!e.crypto?.subtle)throw new p("not_configured","Sign-in needs a secure page (https or localhost).");return new Uint8Array(await e.crypto.subtle.digest("SHA-256",t))},openPopup:()=>{if(!e.window?.open)return null;let t=480,i=640,r=Math.max(0,(e.window.screenX??0)+((e.window.outerWidth??t)-t)/2),n=Math.max(0,(e.window.screenY??0)+((e.window.outerHeight??i)-i)/2);return e.window.open("about:blank","buoy-signin",`popup,width=${t},height=${i},left=${r},top=${n}`)},onMessage:t=>{if(!e.window?.addEventListener)return()=>{};let i=r=>t({origin:r.origin,data:r.data});return e.window.addEventListener("message",i),()=>e.window?.removeEventListener("message",i)},withLock:(t,i)=>e.navigator?.locks?e.navigator.locks.request(t,i):i(),checksPlan:!e.window?.addEventListener||!!e.navigator?.locks,watch:t=>{let i=e.window;if(!i?.addEventListener)return yr(t.wake);let r=s=>t.storage(s.key),n=()=>{i.document?.visibilityState!=="hidden"&&t.wake()};return i.addEventListener("storage",r),i.addEventListener("online",t.wake),i.document?.addEventListener?.("visibilitychange",n),()=>{i.removeEventListener("storage",r),i.removeEventListener("online",t.wake),i.document?.removeEventListener?.("visibilitychange",n)}},setTimer:(t,i)=>setTimeout(t,Math.min(i,2147483647)),clearTimer:t=>clearTimeout(t)}}function yr(e){try{let{AppState:t}=(oi(),ot(z)),i=t?.addEventListener?.("change",r=>{r==="active"&&e()});return()=>i?.remove()}catch{return()=>{}}}function wr(){let e=globalThis.location;if(!(!e?.origin||!/^https?:$/.test(e.protocol??"")))return e.origin}var vr=class{constructor(e){this.signinOrigin=fr;this.current=null;this.claims=null;this.listeners=new Set;this.timer=null;this.refreshing=null;this.loaded=null;this.unwatch=null;this.limitTimer=null;this.epoch=0;this.planRetries=0;this.deps=e??gr(),this.audience=wr()}get origin(){return this.signinOrigin}configure(e){e.audience!==void 0&&(this.audience=e.audience),e.signinOrigin!==void 0&&(this.signinOrigin=e.signinOrigin.replace(/\/$/,"")),this.reset()}reset(){this.planRetries=0,this.unwatch?.(),this.unwatch=null,this.epoch+=1,this.limitTimer!==null&&this.deps.clearTimer(this.limitTimer),this.limitTimer=null,this.timer!==null&&this.deps.clearTimer(this.timer),this.timer=null,this.current=null,this.claims=null,this.loaded=null,this.refreshing=null}get storageKey(){return lr+(this.audience??"")}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}notify(){for(let e of[...this.listeners])try{e()}catch(t){console.warn("[Buoy] sign-in listener error:",t)}}getAccessToken(){let e=this.getStatus();return e.state==="active"&&!e.grace?this.current?.accessToken??null:null}getStatus(){let e=this.claims;if(!e)return{state:"signed_out"};let t=e.exp*1e3,i=this.deps.now();return i<(e.iat-re)*1e3?{state:"signed_out"}:i<t?{state:"active",claims:e,grace:false,validUntil:t}:i<t+$?{state:"active",claims:e,grace:true,validUntil:t+$}:{state:"signed_out"}}load(){return this.loaded||(this.loaded=this.loadOnce()),this.loaded}async loadOnce(){if(!this.audience)return;this.unwatch??(this.unwatch=this.deps.watch?.({storage:t=>{(t===null||t===this.storageKey)&&this.sync()},wake:()=>{this.deps.checksPlan?this.checkPlan():this.claims&&this.refresh()}})??null);let e=await this.read();e&&this.adopt(e)&&(this.notify(),this.schedule(),this.deps.checksPlan&&this.checkPlan())}async sync(){if(!this.audience)return;let e=await this.read();if(!e){this.current&&this.clearLocal();return}e.refreshToken!==this.current?.refreshToken&&this.adopt(e)&&(this.notify(),this.schedule())}async read(){try{let e=await(await this.deps.storage()).getItem(this.storageKey);if(!e)return null;let t=JSON.parse(e);return t?.v===1&&typeof t.accessToken=="string"&&typeof t.refreshToken=="string"?t:null}catch{return null}}async write(e){let t=await this.deps.storage();e?await t.setItem(this.storageKey,JSON.stringify(e)):await t.removeItem(this.storageKey)}adopt(e){if(!this.audience)return false;let t=se(e.accessToken,{audience:this.audience,ignoreTime:true}),i=t.ok?t.claims:null;return i?(this.current=e,this.claims=i,true):false}armLimit(){if(this.limitTimer!==null&&this.deps.clearTimer(this.limitTimer),this.limitTimer=null,!this.claims)return;let e=this.claims.exp*1e3,t=this.deps.now(),i=t<e?e:t<e+$?e+$:null;i!==null&&(this.limitTimer=this.deps.setTimer(()=>{this.limitTimer=null,this.notify(),this.armLimit()},i-t))}call(e,t){return new Promise((i,r)=>{let n=this.deps.setTimer(()=>r(new Error("timeout")),ur);this.deps.fetch(e,t).then(s=>{this.deps.clearTimer(n),i(s)},s=>{this.deps.clearTimer(n),r(s)})})}schedule(){if(this.armLimit(),this.timer!==null&&this.deps.clearTimer(this.timer),this.timer=null,!this.claims)return;let e=this.claims.exp*1e3-Qe-this.deps.now();this.timer=this.deps.setTimer(()=>{this.timer=null,this.refresh()},Math.max(0,e))}refresh(e=false){return this.startRefresh(()=>this.refreshLocked(e))}checkPlan(e=cr){return this.startRefresh(()=>this.refreshLocked(false,e))}retryPlanCheck(){if(this.planRetries>=2){this.planRetries=0,this.schedule();return}this.planRetries+=1,this.timer!==null&&this.deps.clearTimer(this.timer),this.timer=this.deps.setTimer(()=>{this.timer=null,this.checkPlan(0)},hr)}startRefresh(e){return this.refreshing||(this.refreshing=this.deps.withLock(this.lockName,e).catch(()=>this.retryLater()).finally(()=>{this.refreshing=null})),this.refreshing}get lockName(){return`buoy-session:${this.audience??""}`}async refreshLocked(e,t){let i=this.epoch,r=await this.read();if(!r){this.current&&this.clearLocal();return}if(r.refreshToken!==this.current?.refreshToken&&this.adopt(r)){this.notify(),this.schedule();return}if(!this.claims)return;let n=this.claims.exp*1e3-this.deps.now()>Qe,s=!e&&n&&t!==void 0,h=s&&this.planRetries>0&&this.timer===null,c=s&&this.deps.now()-this.claims.iat*1e3>=t;if(!e&&n&&!c&&!h){this.planRetries||this.schedule();return}let a=()=>s?this.retryPlanCheck():this.retryLater(),l,o;try{let d=await this.call(`${this.signinOrigin}/api/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refresh_token:r.refreshToken,audience:this.audience})});l=d.status,o=await d.json().catch(()=>null)}catch{i===this.epoch&&a();return}if(i===this.epoch){if(l===200&&o&&typeof o.access_token=="string"&&typeof o.refresh_token=="string"){let d={v:1,accessToken:o.access_token,refreshToken:o.refresh_token};if(this.adopt(d)){this.planRetries=0,await this.write(d),this.notify(),this.schedule();return}}if(l===400||l===401||l===403){await this.write(null),this.clearLocal();return}a()}}retryLater(){this.armLimit(),this.timer!==null&&this.deps.clearTimer(this.timer),this.timer=this.deps.setTimer(()=>{this.timer=null,this.refresh(true)},dr),this.notify()}clearLocal(){this.planRetries=0,this.timer!==null&&this.deps.clearTimer(this.timer),this.timer=null,this.limitTimer!==null&&this.deps.clearTimer(this.limitTimer),this.limitTimer=null,this.current=null,this.claims=null,this.notify()}async signIn(){if(!this.audience)throw new p("not_configured","Sign-in needs a web page or a configured app id.");let e=this.deps.openPopup();if(!e)throw new p("popup_blocked","The browser blocked the sign-in window. Allow pop-ups for this site and try again.");try{return await this.signInWith((t,i)=>new Promise((r,n)=>{e.location.href=t;let s=this.deps.now(),h=null,c=o=>{h!==null&&this.deps.clearTimer(h),a(),o()},a=this.deps.onMessage(o=>{if(o.origin!==this.signinOrigin)return;let d=o.data;!d||d.type!==pr||d.state!==i||(typeof d.code=="string"?c(()=>r(d.code)):c(()=>n(new p("access_denied","Sign-in was cancelled."))))}),l=()=>{if(e.closed)return c(()=>n(new p("popup_closed","The sign-in window was closed.")));if(this.deps.now()-s>mr)return c(()=>n(new p("timeout","Sign-in took too long.")));h=this.deps.setTimer(l,500)};h=this.deps.setTimer(l,500)}))}finally{try{e.closed||e.close()}catch{}}}async signInWith(e){let t=this.audience;if(!t)throw new p("not_configured","Sign-in needs a web page or a configured app id.");let i=ne(this.deps.random(32)),r=ne(this.deps.random(16)),n=ne(await this.deps.sha256(new TextEncoder().encode(i))),s=`${this.signinOrigin}/auth/authorize?audience=${encodeURIComponent(t)}&code_challenge=${n}&code_challenge_method=S256&state=${r}`,h=await e(s,r),c;try{c=await this.call(`${this.signinOrigin}/api/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:h,code_verifier:i,audience:t})})}catch{throw new p("network","Buoy could not be reached. Check your connection and try again.")}let a=await c.json().catch(()=>null);if(c.status!==200||!a||typeof a.access_token!="string"||typeof a.refresh_token!="string"){let l=a&&typeof a.error_description=="string"?a.error_description:"Buoy did not accept this sign-in.";throw new p(c.status===503?"unavailable":"rejected",l)}return this.finishSignIn(a.access_token,a.refresh_token)}async finishSignIn(e,t){let i={v:1,accessToken:e,refreshToken:t};if(this.epoch+=1,!this.adopt(i))throw new p("rejected","Buoy sent a sign-in this app could not check.");return await this.write(i),await this.load(),this.notify(),this.schedule(),this.getStatus()}async signInWithCode(e,t={}){let i=this.audience;if(!i)throw new p("not_configured","Sign-in with a code needs this app's id (app:com.example.app).");let r=(a,l)=>this.call(`${this.signinOrigin}/api/auth/device/${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(l)}),n;try{n=await r("start",{audience:i})}catch{throw new p("network","Buoy could not be reached. Check your connection and try again.")}let s=await n.json().catch(()=>null);if(n.status!==200||!s||typeof s.device_code!="string"||typeof s.user_code!="string"||typeof s.verification_uri!="string"||typeof s.verification_uri_complete!="string"){let a=s&&typeof s.error_description=="string"?s.error_description:"Buoy could not start a sign-in.";throw new p(n.status===503?"unavailable":"rejected",a)}let h=this.deps.now()+(Number(s.expires_in)||600)*1e3,c=Math.max(5,Number(s.interval)||5)*1e3;for(e({userCode:s.user_code,verificationUri:s.verification_uri,verificationUriComplete:s.verification_uri_complete,expiresAt:h});;){if(await this.wait(c,t.signal),this.deps.now()>h)throw new p("timeout","The code ran out. Start again for a new one.");let a;try{a=await r("poll",{device_code:s.device_code})}catch{continue}let l=await a.json().catch(()=>null);if(a.status===200&&l&&typeof l.access_token=="string"&&typeof l.refresh_token=="string")return this.finishSignIn(l.access_token,l.refresh_token);let o=l&&typeof l.error=="string"?l.error:"";if(o==="authorization_pending"||a.status>=500)continue;if(o==="slow_down"||a.status===429){c+=5e3;continue}if(o==="access_denied")throw new p("access_denied","The sign-in was turned down on buoy.gg.");if(o==="expired_token")throw new p("timeout","The code ran out. Start again for a new one.");let d=l&&typeof l.error_description=="string"?l.error_description:"Buoy did not accept this sign-in.";throw new p("rejected",d)}}wait(e,t){return new Promise((i,r)=>{let n=()=>new p("access_denied","Sign-in was cancelled.");if(t?.aborted)return r(n());let s=()=>{this.deps.clearTimer(h),r(n())},h=this.deps.setTimer(()=>{t?.removeEventListener?.("abort",s),i()},e);t?.addEventListener?.("abort",s)})}async signOut(){this.epoch+=1;let e=this.current;this.clearLocal();let t=e;try{await this.deps.withLock(this.lockName,async()=>{t=await this.read()??e,await this.write(null)})}catch{await this.write(null).catch(()=>{})}if(t)try{await this.call(`${this.signinOrigin}/api/auth/revoke`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refresh_token:t.refreshToken})})}catch{}}},_=new vr;f();var br="bsk1_",Tr="service",Ar=15e3;function ae(e){return e.startsWith(br)}function N(e){let t=e.trim();return ae(t)||Ze(t)?t:t.toUpperCase()}function kr(e,t){return N(e??"")===N(t??"")}async function Er(e,t){let i=t.fetch??((a,l)=>fetch(a,l)),r=typeof AbortController<"u"?new AbortController:void 0,n=setTimeout(()=>r?.abort(),Ar),s,h;try{let a=await i(`${t.origin.replace(/\/$/,"")}/api/auth/service-token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({key:e}),signal:r?.signal});s=a.status,h=await a.json().catch(()=>null)}catch{return{ok:false,reason:"network",detail:"Buoy could not be reached to check the bot key."}}finally{clearTimeout(n)}if(s>=500||s===429)return{ok:false,reason:"network",detail:"Buoy is busy. The bot key will be checked again soon."};if(s!==200||typeof h?.access_token!="string")return{ok:false,reason:"rejected",detail:typeof h?.error_description=="string"?h.error_description:"This bot key was not accepted."};let c=se(h.access_token,{audience:Tr,nowMs:u()});return c.ok?{ok:true,claims:c.claims}:{ok:false,reason:"rejected",detail:"Buoy sent a token this app could not check."}}f();var xr="dev";function et(e){return Ze(e)}function tt(e,t=u()){let i=se(e,{audience:xr,ignoreTime:true});return i.ok?t>=i.claims.exp*1e3?{ok:false,reason:"expired",message:"Your dev token ran out. Run `npx --package=@buoy-gg/core buoy login` again."}:{ok:true,claims:i.claims}:{ok:false,reason:"invalid",message:"This dev token is not valid. Run `npx --package=@buoy-gg/core buoy login` again."}}var _r="This is a dev token. It only works in dev builds. A live build turns on Buoy with Sign in with Buoy.";var Lr={role:null,tools:null};function it(e){return{role:e.role??null,tools:e.tools??null}}async function b(e,t){let i;try{return await Promise.race([e,new Promise(r=>{i=setTimeout(()=>r(t),15e3)})])}finally{i&&clearTimeout(i)}}function P(e){return e.tier==="pro"||e.tier==="free"?e.tier:e.isPro?"pro":"free"}var Sr=class{constructor(){this.state={isInitialized:false,isValidating:false,isPro:false,tier:"free",tierSource:"none",licenseKey:null,error:null,errorKind:null,expiresAt:null};this.listeners=new Set;this.revalidationTimer=null;this.cachedLicense=null;this.fingerprintPromise=null;this.fingerprintRestored=false;this.initPromise=null;this.generation=0;this.persistence=Promise.resolve();this.verifiedAt=null;this.expiryTimer=null;this.removeForegroundListener=null;this.sessionUnsubscribe=null;this.devToken=null;this.retryTimer=null;this.retryAttempt=0;this.deviceRegistrationCallback=null;this.pendingRegistration=null}async initialize(){if(this.initPromise)return this.initPromise;if(!this.state.isInitialized)return this.initPromise=this._doInitialize(),this.initPromise}async _doInitialize(){if(this.state.isInitialized)return;let e=this.generation;this.sessionUnsubscribe||(this.sessionUnsubscribe=_.subscribe(()=>this.emit({type:"validated",isPro:this.isPro()}))),await b(_.load().catch(()=>{}),void 0);try{let t=await b(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)){let i=R(t);this.cachedLicense=t,this.state.licenseKey=t.licenseKey,i&&this.isCacheValid(t)?this.applyTier(P(t)):this.lock(),this.state.expiresAt=t.expiresAt?new Date(t.expiresAt):null,i&&this.isCacheValid(t)&&this.setVerifiedAt(t.cachedAt),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("[Buoy]","[React Buoy] License initialization failed:",t),this.state.isInitialized=true,this.emit({type:"initialized",isPro:false})}}async configure(e){if(e===void 0)return await this.initialize(),this.hasAccountAccess();let t=N(e),i=++this.generation;return this.cancelRetry(),this.configuredKey=t||null,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(),i!==this.generation?false:t?this.setLicenseKey(t):(await this.clearLicense(),false)}async setLicenseKey(e,t){if(!e||e.trim().length===0)return this.state.error="License key is required",this.state.errorKind="verdict",false;let i=N(e),r=++this.generation;if(this.cancelRetry(),t?.isRetry||(this.retryAttempt=0),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()}),ze(i))return this.admitToken(i,r);if(ae(i))return this.admitServiceKey(i,r);if(et(i))return this.admitDevToken(i);if(!this.cachedLicense){let a=await b(this.loadCachedLicense(),null);if(r!==this.generation)return false;a?.licenseKey===i&&(this.cachedLicense=a,R(a)&&this.isCacheValid(a)&&(this.applyTier(P(a)),this.state.expiresAt=a.expiresAt?new Date(a.expiresAt):null,this.setVerifiedAt(a.cachedAt),this.emit({type:"validating",isPro:this.isPro()})))}let n=this.cachedLicense;if(!t?.force&&n&&n.valid&&n.licenseKey===i&&n.fingerprint&&R(n)&&this.isCacheValid(n)&&this.isCacheFresh(n))return this.applyTier(P(n)),this.state.licenseKey=i,this.state.isValidating=false,this.state.error=null,this.state.errorKind=null,this.state.expiresAt=n.expiresAt?new Date(n.expiresAt):null,this.setVerifiedAt(n.cachedAt),this.emit({type:"validated",isPro:this.state.isPro}),true;let s=await b(this.loadHold(),null);if(r!==this.generation)return false;let h=(s?.backoffUntil??0)-u();if(h>0)return this.standDown(i,r,"License server is rate limited; retrying later.",h);if(!t?.force&&s?.key===i&&s.verdictAt!==void 0&&u()-s.verdictAt>=0&&u()-s.verdictAt<mi)return this.lock(),this.state.isValidating=false,this.state.error=s.detail||"License could not be verified",this.state.errorKind="verdict",this.emit({type:"error",isPro:false,error:this.state.error}),false;let c;try{c=await ki(i)}catch(a){let l=a instanceof Error?a.message:"Validation failed";if(r!==this.generation)return false;if(Ke(a)){if(wi(a)){let o=Math.min(vi(a,Pe,pi)*2**this.retryAttempt,Pe);return this.retryAttempt+=1,await this.saveHold({...this.hold,backoffUntil:u()+o}),r!==this.generation?false:this.standDown(i,r,l,o)}return this.state.isValidating=false,this.cachedLicense&&this.cachedLicense.licenseKey===i&&R(this.cachedLicense)&&this.isCacheValid(this.cachedLicense)?(this.applyTier(P(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),this.keyTier()!=="pro"&&this.scheduleRetry(i),this.emit({type:"validated",isPro:this.state.isPro}),true):(this.state.error=l,this.state.errorKind="transport",this.scheduleRetry(i),this.emit({type:"error",isPro:this.state.isPro,error:l}),false)}return this.state.isValidating=false,this.state.error=l,this.state.errorKind="verdict",this.emit({type:"error",isPro:false,error:l}),false}try{if(r!==this.generation)return false;let a=_i(c),l=c.data?.relationships?.product?.data?.id;if((!l||l===M.productId)&&a.code==="EXPIRED"&&(Xi(c.data)||this.cachedLicense?.licenseKey===i&&R(this.cachedLicense)&&this.isCacheValid(this.cachedLicense))){let B=u(),he=await this.saveCache({licenseKey:i,licenseId:c.data?.id??"",valid:true,isPro:false,tier:"free",expiresAt:null,cachedAt:B,lastValidatedAt:B,fingerprint:this.cachedLicense?.licenseKey===i?this.cachedLicense.fingerprint:void 0},r);return r!==this.generation||!he?false:(this.cachedLicense=he,this.applyTier("free"),this.state.isValidating=false,this.state.expiresAt=null,this.setVerifiedAt(B),this.emit({type:"validated",isPro:false}),true)}if(Li(a.code)||!Ei(c))return 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:u()}),false;if(!c.data)return 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(),false;let o=Ji(c.data),d=c.data.id,A=u(),k=xi(c)>=gi,oe=te(),rt=oe&&!k,nt=o==="free"&&(k||!oe),L=this.cachedLicense?.fingerprint,K=this.cachedLicense?.deviceName,le=false;if(!L){if(L=await b(this.getOrCreateDeviceFingerprint(),ee()),r!==this.generation)return false;K=ie(),le=rt}let U=false;le&&(this.deviceRegistrationCallback?(this.pendingRegistration={licenseId:d,licenseKey:i,fingerprint:L},this.deviceRegistrationCallback({fingerprint:L,defaultName:K}),U=true):this.registerDeviceAsync(d,i,L,K));let F={licenseKey:i,licenseId:d,valid:true,isPro:o==="pro",tier:o,expiresAt:c.data.attributes.expiry??null,cachedAt:A,lastValidatedAt:A,fingerprint:U?void 0:L,deviceName:U?void 0:K,quiet:nt||void 0},ce=await this.saveCache(F,r);return r!==this.generation||!ce||(this.cachedLicense=ce,this.applyTier(o),this.state.isValidating=false,this.state.expiresAt=F.expiresAt?new Date(F.expiresAt):null,this.setVerifiedAt(A),this.hold&&await this.saveHold(null),r!==this.generation)?false:(this.retryAttempt=0,this.emit({type:"validated",isPro:this.state.isPro}),true)}catch(a){let l=a instanceof Error?a.message:"Validation failed";return r!==this.generation||(this.state.isValidating=false,this.state.error=l,this.state.errorKind="verdict",this.emit({type:"error",isPro:false,error:l})),false}}scheduleRetry(e){this.cancelRetry();let t=fi[this.retryAttempt];if(t===void 0)return;this.retryAttempt+=1;let i=this.generation;this.retryTimer=setTimeout(()=>{this.retryTimer=null,i===this.generation&&(this.state.isValidating||this.setLicenseKey(e,{force:true,isRetry:true}))},t),typeof m<"u"&&m&&(globalThis.__LICENSE_MANAGER_RETRY_TIMER__=this.retryTimer)}async admitServiceKey(e,t){let i=await Er(e,{origin:_.origin});if(t!==this.generation)return false;if(!i.ok)return this.lock(),this.state.isValidating=false,this.state.error=i.detail,this.state.errorKind=i.reason==="network"?"transport":"verdict",this.emit({type:"error",isPro:false,error:i.detail}),i.reason==="network"&&this.scheduleRetry(e),false;let r=i.claims.exp*1e3;return this.applyTier(i.claims.tier==="free"?"free":"pro"),this.state.isValidating=false,this.state.expiresAt=new Date(r),this.setVerifiedAt(u()),this.retryAttempt=0,this.scheduleRetryIn(e,Math.max(6e4,r-3600*1e3-u())),this.emit({type:"validated",isPro:this.isPro()}),true}admitDevToken(e){let t=tt(e);if(!t.ok||!te()){let r=t.ok?_r:t.message;return this.lock(),this.state.isValidating=false,this.state.error=r,this.state.errorKind="verdict",this.emit({type:"error",isPro:false,error:r}),false}let i=u();return this.devToken={token:e,claims:t.claims},this.applyTier(t.claims.tier==="free"?"free":"pro"),this.state.isValidating=false,this.state.expiresAt=new Date(t.claims.exp*1e3),this.setVerifiedAt(Math.min(i,t.claims.iat*1e3)),this.retryAttempt=0,this.emit({type:"validated",isPro:this.isPro()}),true}async admitToken(e,t){let i=Wi(e);if(t!==this.generation)return false;if(!i)return 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(),false;let r=u(),n=this.cachedLicense?.fingerprint??await b(this.getOrCreateDeviceFingerprint(),ee());if(t!==this.generation)return false;let s=await this.saveCache({licenseKey:e,licenseId:`token:${i.accountHash}`,valid:true,isPro:false,tier:"free",expiresAt:null,cachedAt:r,lastValidatedAt:r,fingerprint:n,deviceName:this.cachedLicense?.deviceName??ie(),quiet:true},t);return t!==this.generation||!s?false:(this.cachedLicense=s,this.applyTier("free"),this.state.isValidating=false,this.state.expiresAt=null,this.setVerifiedAt(r),this.retryAttempt=0,this.emit({type:"validated",isPro:false}),true)}standDown(e,t,i,r){if(t!==this.generation)return false;this.state.isValidating=false;let n=this.cachedLicense;return n&&n.licenseKey===e&&R(n)&&this.isCacheValid(n)?(this.applyTier(P(n)),this.state.error=null,this.state.errorKind=null,this.state.expiresAt=n.expiresAt?new Date(n.expiresAt):null,this.setVerifiedAt(n.cachedAt),this.keyTier()!=="pro"&&this.scheduleRetryIn(e,r),this.emit({type:"validated",isPro:this.state.isPro}),true):(this.state.error=i,this.state.errorKind="transport",this.scheduleRetryIn(e,r),this.emit({type:"error",isPro:this.state.isPro,error:i}),false)}scheduleRetryIn(e,t){this.cancelRetry();let i=this.generation;this.retryTimer=setTimeout(()=>{this.retryTimer=null,i===this.generation&&(this.state.isValidating||this.setLicenseKey(e,{force:true,isRetry:true}))},Math.max(1,Math.min(t,2147483647))),typeof m<"u"&&m&&(w.__LICENSE_MANAGER_RETRY_TIMER__=this.retryTimer)}cancelRetry(){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(),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,this.expiryTimer&&clearTimeout(this.expiryTimer),this.expiryTimer=null}getTier(){return this.credential().tier}credential(){let e=this.keyTier(),t=this.sessionTier();return t!==null&&(!this.hasKeyAccess()||t==="pro"&&e!=="pro")?{source:"session",tier:t}:{source:this.state.tierSource,tier:e}}keyTier(){return!this.hasKeyAccess()||this.state.expiresAt&&u()>=this.state.expiresAt.getTime()?"free":this.state.tier}sessionTier(){let e=_.getStatus();return e.state!=="active"?null:e.claims.tier==="free"?"free":"pro"}isPro(){return this.getTier()==="pro"}hasEntitlement(e){return this.isPro()}getState(){let{source:e,tier:t}=this.credential(),i=this.getTeamAccess();return{...this.state,tier:t,tierSource:e,isPro:t==="pro",access:this.getAccountAccess(),teamRole:i.role,allowedTools:i.tools}}getTeamAccess(){let e=_.getStatus();if(e.state==="active")return it(e.claims);let t=this.devToken;return t&&t.token===this.state.licenseKey&&this.state.tierSource==="key"&&u()<t.claims.exp*1e3&&this.hasKeyAccess()?it(t.claims):Lr}getAccountAccess(){let e=this.getKeyAccess();if(e.status==="admitted")return e;let t=_.getStatus();return t.state==="active"?{status:"admitted",reason:null,validUntil:t.validUntil}:e}getKeyAccess(){return Ye({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"}hasKeyAccess(){return this.getKeyAccess().status==="admitted"}setVerifiedAt(e){this.verifiedAt=e,this.expiryTimer&&clearTimeout(this.expiryTimer);let t=e+D,i=this.state.expiresAt?.getTime(),r=(i&&i>u()?Math.min(t,i):t)-u();this.expiryTimer=setTimeout(()=>{this.expiryTimer=null,this.verifiedAt===e&&(this.emit({type:"validated",isPro:this.isPro()}),u()<t&&this.setVerifiedAt(e))},Math.max(1,Math.min(r,2147483647))),typeof m<"u"&&m&&(w.__LICENSE_MANAGER_EXPIRY_TIMER__=this.expiryTimer)}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}onDeviceRegistrationNeeded(e){return this.deviceRegistrationCallback=e,()=>{this.deviceRegistrationCallback=null}}async completeDeviceRegistration(e){if(!this.pendingRegistration){console.warn("[Buoy] No pending device registration");return}let{licenseId:t,licenseKey:i,fingerprint:r}=this.pendingRegistration,n=this.generation,s=e.trim()||ie(),h=$e();try{await Me(t,i,r,s,h)}catch(c){let a=c instanceof Error?c.message:String(c);if(!(a==="FINGERPRINT_TAKEN"||a==="MACHINE_LIMIT_EXCEEDED"))throw console.warn("[Buoy] Device registration failed:",a),c}if(n===this.generation){if(this.cachedLicense?.licenseKey===i){let c=await this.saveCache({...this.cachedLicense,fingerprint:r,deviceName:s},n);if(n!==this.generation)return;c&&(this.cachedLicense=c)}this.pendingRegistration=null}}emit(e){[...this.listeners].forEach(t=>{try{t(e)}catch(i){console.warn("[Buoy]","[React Buoy] License listener error:",i)}})}isCacheValid(e){let t=u()-e.cachedAt;return!(!e.valid||!Number.isFinite(e.cachedAt)||t<0||t>=D)}isCacheFresh(e){let t=this.isQuiet(e)?yi:ui;return u()-(e.lastValidatedAt??0)<t}isQuiet(e){return e.quiet!==void 0?e.quiet:P(e)==="free"&&!te()}async loadHold(){if(this.hold!==void 0)return this.hold;try{let e=await(await T()).getItem(Q),t=e?JSON.parse(e):null;this.hold=t&&typeof t=="object"?t:null}catch{this.hold=null}return this.hold}async saveHold(e){this.hold=e;try{let t=await T();e?await t.setItem(Q,JSON.stringify(e)):await t.removeItem(Q)}catch{}}async persistCache(e){let t=je(e);return await(await T()).setItem(q,JSON.stringify(t)),t}saveCache(e,t){let i=this.persistence.catch(()=>{}).then(async()=>{if(t!==this.generation)return null;let r=await this.persistCache(e);return t===this.generation?r:null});return this.persistence=i,b(i,je(e))}async loadCachedLicense(){try{await this.persistence.catch(()=>{});let e=await(await T()).getItem(q);if(!e)return null;let t=JSON.parse(e);if(t.fingerprint){let i=await b(this.getOrCreateDeviceFingerprint(t.fingerprint).catch(()=>null),null);if(i&&this.fingerprintRestored&&t.fingerprint!==i)return{...t,fingerprint:void 0,deviceName:void 0}}return t}catch(e){return console.warn("[Buoy] Error loading cached license:",e),null}}getOrCreateDeviceFingerprint(e){return this.fingerprintPromise||(this.fingerprintPromise=(async()=>{let t=await T(),i=await t.getItem(Z),r=await t.getItem(Ce),n=await b(Ii().catch(()=>null),null),s=Ri({stored:i,storedOwner:r,marker:n?Ci(n):null,blobFingerprint:e??this.cachedLicense?.fingerprint,mint:ee});return this.fingerprintRestored=s.restored,s.changed&&(await t.setItem(Z,s.fingerprint),s.owner&&await t.setItem(Ce,s.owner)),s.fingerprint})()),this.fingerprintPromise}async clearCachedLicense(){this.cachedLicense=null;let e=this.persistence.catch(()=>{}).then(async()=>{await(await T()).removeItem(q)});this.persistence=e,await b(e.catch(()=>{}),void 0)}registerDeviceAsync(e,t,i,r){let n=$e();Me(e,t,i,r,n).catch(s=>{s.message!=="FINGERPRINT_TAKEN"&&s.message!=="MACHINE_LIMIT_EXCEEDED"&&console.warn("[Buoy] Device registration failed (non-blocking):",s.message)})}validateInBackground(e){this.setLicenseKey(e,{force:true,isRetry:true})}refreshAccess(){this.emit({type:"validated",isPro:this.isPro()})}startRevalidationTimer(){this.removeForegroundListener||(this.removeForegroundListener=qi(()=>this.refreshAccess()),typeof m<"u"&&m&&(w.__LICENSE_MANAGER_FOREGROUND_OFF__=this.removeForegroundListener)),this.revalidationTimer&&clearInterval(this.revalidationTimer),this.revalidationTimer=setInterval(()=>{if(!this.state.licenseKey||this.state.isValidating)return;let e=this.cachedLicense;e&&e.licenseKey===this.state.licenseKey&&this.isCacheFresh(e)||this.validateInBackground(this.state.licenseKey)},di),typeof m<"u"&&m&&(globalThis.__LICENSE_MANAGER_TIMER__=this.revalidationTimer)}stopRevalidationTimer(){this.removeForegroundListener?.(),this.removeForegroundListener=null,this.expiryTimer&&clearTimeout(this.expiryTimer),this.expiryTimer=null,this.revalidationTimer&&(clearInterval(this.revalidationTimer),this.revalidationTimer=null),this.cancelRetry()}async forceReregister(){this.cachedLicense&&(this.cachedLicense.fingerprint=void 0,this.cachedLicense.deviceName=void 0),this.fingerprintPromise=null,await this.clearCachedLicense();try{await(await T()).removeItem(Z)}catch{}}},Ir=new Sr,w=globalThis;typeof m<"u"&&m&&(w.__LICENSE_MANAGER_FOREGROUND_OFF__?.(),w.__LICENSE_MANAGER_FOREGROUND_OFF__=void 0,w.__LICENSE_MANAGER_EXPIRY_TIMER__&&clearTimeout(w.__LICENSE_MANAGER_EXPIRY_TIMER__),w.__LICENSE_MANAGER_TIMER__&&clearInterval(w.__LICENSE_MANAGER_TIMER__),w.__LICENSE_MANAGER_RETRY_TIMER__&&(clearTimeout(w.__LICENSE_MANAGER_RETRY_TIMER__),w.__LICENSE_MANAGER_RETRY_TIMER__=void 0));export{u as a,I as b,Ke as c,ze as d,Ye as e,p as f,_ as g,ae as h,N as i,kr as j,et as k,tt as l,Ir as m};/*!
|
|
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
|
+
* PROPRIETARY — Buoy Pro license enforcement. NOT open source.
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
|
10
|
+
* (https://buoy.gg/terms), not an OSS license.
|
|
11
|
+
*
|
|
12
|
+
* This file configures the technological measure that controls access to paid
|
|
13
|
+
* Buoy Pro features. Modifying, patching, aliasing, stubbing, or otherwise
|
|
14
|
+
* altering it — including repointing `apiUrl` at a stand-in license server — so
|
|
15
|
+
* that Pro features unlock without a valid license is a breach of the EULA and,
|
|
16
|
+
* in the United States, circumvention of an access control under 17 U.S.C.
|
|
17
|
+
* § 1201, which applies whether or not any code is copied.
|
|
18
|
+
*
|
|
19
|
+
* Pro is $9/mo, and is free every weekend for anyone holding a key —
|
|
20
|
+
* including a free one (`npx --package=@buoy-gg/core buoy login`). Buy a key at
|
|
21
|
+
* https://buoy.gg or use it free on Saturday and Sunday.
|
|
22
|
+
*//*!
|
|
23
|
+
* PROPRIETARY — Buoy Pro license enforcement. NOT open source.
|
|
24
|
+
*
|
|
25
|
+
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
|
26
|
+
* (https://buoy.gg/terms), not an OSS license.
|
|
27
|
+
*
|
|
28
|
+
* This file is part of the technological measure that controls access to paid
|
|
29
|
+
* Buoy Pro features. Modifying, patching, aliasing, stubbing, or otherwise
|
|
30
|
+
* altering it so that Pro features unlock without a valid license is a breach
|
|
31
|
+
* of the EULA and, in the United States, circumvention of an access control
|
|
32
|
+
* under 17 U.S.C. § 1201 — which applies whether or not any code is copied.
|
|
33
|
+
*
|
|
34
|
+
* Pro is $9/mo, and is free every weekend for anyone holding a key —
|
|
35
|
+
* including a free one (`npx --package=@buoy-gg/core buoy login`). Buy a key at
|
|
36
|
+
* https://buoy.gg or use it free on Saturday and Sunday.
|
|
37
|
+
*//*!
|
|
38
|
+
* PROPRIETARY — Buoy Pro license enforcement. NOT open source.
|
|
39
|
+
*
|
|
40
|
+
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
|
41
|
+
* (https://buoy.gg/terms), not an OSS license.
|
|
42
|
+
*
|
|
43
|
+
* This file is part of the technological measure that controls access to paid
|
|
44
|
+
* Buoy Pro features: it decides which tier a validated key grants. Modifying,
|
|
45
|
+
* patching, aliasing, stubbing, or otherwise altering it so that Pro features
|
|
46
|
+
* unlock without a valid license is a breach of the EULA and, in the United
|
|
47
|
+
* States, circumvention of an access control under 17 U.S.C. § 1201 — which
|
|
48
|
+
* applies whether or not any code is copied.
|
|
49
|
+
*
|
|
50
|
+
* Pro is $9/mo, and is free every weekend for anyone holding a key —
|
|
51
|
+
* including a free one (`npx --package=@buoy-gg/core buoy login`). Buy a key at
|
|
52
|
+
* https://buoy.gg or use it free on Saturday and Sunday.
|
|
53
|
+
*//*!
|
|
54
|
+
* PROPRIETARY — Buoy license enforcement. NOT open source.
|
|
55
|
+
*
|
|
56
|
+
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
|
57
|
+
* (https://buoy.gg/terms), not an OSS license.
|
|
58
|
+
*//*!
|
|
59
|
+
* PROPRIETARY — Buoy Pro license enforcement. NOT open source.
|
|
60
|
+
*
|
|
61
|
+
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
|
62
|
+
* (https://buoy.gg/terms), not an OSS license.
|
|
63
|
+
*
|
|
64
|
+
* This file is the technological measure that controls access to paid Buoy Pro
|
|
65
|
+
* features. Modifying, patching, aliasing, stubbing, or otherwise altering it
|
|
66
|
+
* so that Pro features unlock without a valid license is a breach of the EULA
|
|
67
|
+
* and, in the United States, circumvention of an access control under
|
|
68
|
+
* 17 U.S.C. § 1201 — which applies whether or not any code is copied.
|
|
69
|
+
*
|
|
70
|
+
* Pro is $9/mo, and is free every weekend for anyone holding a key —
|
|
71
|
+
* including a free one (`npx --package=@buoy-gg/core buoy login`). Buy a key at
|
|
72
|
+
* https://buoy.gg or use it free on Saturday and Sunday.
|
|
73
|
+
*/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";var o=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var s=(e,r)=>()=>(e&&(r=e(e=0)),r);var g=(e,r)=>{for(var t in r)o(e,t,{get:r[t],enumerable:true})},n=(e,r,t,i)=>{if(r&&typeof r=="object"||typeof r=="function")for(let a of v(r))!y.call(e,a)&&a!==t&&o(e,a,{get:()=>r[a],enumerable:!(i=b(r,a))||i.enumerable});return e},d=(e,r,t)=>(n(e,r,"default"),t&&n(t,r,"default"));var h=e=>n(o({},"__esModule",{value:true}),e);var f,c=s(()=>{"use strict";f=(()=>{try{let e=globalThis.Capacitor;if(e&&typeof e.isNativePlatform=="function"&&e.isNativePlatform())return e.DEBUG===true}catch{}return process.env.NODE_ENV!=="production"})();typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis)});c();function l(){let e=globalThis.Capacitor;return e&&typeof e=="object"?e:null}function u(){try{return l()?.isNativePlatform?.()===true}catch{return false}}function m(){if(!u())return null;try{let e=l()?.getPlatform?.();return e==="ios"||e==="android"?e:null}catch{return null}}function p(){return u()?l()?.DEBUG===true:null}function P(e){return p()??e}export{s as a,g as b,d as c,h as d,f as e,c as f,u as g,m as h,p as i,P as j};
|
package/lib/web/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use client";import{a as
|
|
1
|
+
"use client";import{a as _,b as K,c as h,d as L,e as P,f as B,g as I,h as Y,i as O,j as b,k as v,l as T,m as U,n as N,o as w,p as z,q as D,r as W,s as j}from"./chunks/chunk-KGEZ5TEJ.mjs";import{a as F,b as M,c as V,d as H,e as Q,f as X,g as r,h as $,i as q,j as x,k as p,l as d,m as n}from"./chunks/chunk-U4JDBLRG.mjs";import{f as o,g as R,h as G,i as J,j as Z}from"./chunks/chunk-YHWYXKID.mjs";o();o();import{useEffect as ee,useState as se}from"react";function l(e=new Date(F())){if(globalThis.__buoyWeekendPassOff===true)return false;let s=e.getDay();return s===0||s===6}function f(){let[e,s]=se(()=>l());return ee(()=>{let a=setInterval(()=>{let t=l();s(i=>i===t?i:t)},6e4);return()=>clearInterval(a)},[]),e}function m(e,s){return s&&e}o();import{useState as C,useEffect as y,useCallback as g}from"react";function c(){let[e,s]=C(n.getState());y(()=>{let i=n.subscribe(u=>{s(n.getState())});return n.initialize().then(()=>{s(n.getState())}),i},[]);let a=g(async i=>{let u=await n.setLicenseKey(i,{force:true});return s(n.getState()),u},[]),t=g(async()=>{await n.clearLicense(),s(n.getState())},[]);return{...e,setLicenseKey:a,clearLicense:t}}function te(){return c().access}function ae(){let{tier:e,isInitialized:s}=c();return s?e:"free"}function ie(e){let{isPro:s,isInitialized:a,isValidating:t}=c();return{hasAccess:s,isPro:s,isLoading:!a||t}}function ne(){let{isPro:e,isInitialized:s,access:a}=c(),t=m(a.status==="admitted",f());return s&&e||t}function re(){let{isPro:e,isInitialized:s,access:a}=c(),t=s&&e,i=m(a.status==="admitted",f())&&!t;return{isPro:t||i,isLicensed:t,isWeekendFree:i,reason:t?"licensed":i?"weekend":null}}function ce(){let[e,s]=C(()=>r.getStatus());y(()=>{let i=()=>s(r.getStatus()),u=r.subscribe(i);return r.load().then(i,i),u},[]);let a=g(()=>r.signIn(),[]),t=g(()=>r.signOut(),[]);return{status:e,signIn:a,signOut:t}}o();var A=["BUOY_LICENSE_KEY","BUOY_KEY","EXPO_PUBLIC_BUOY_KEY","VITE_BUOY_KEY","NEXT_PUBLIC_BUOY_KEY","REACT_APP_BUOY_KEY","licenseKey"],oe=/(^|_)BUOY_(LICENSE_)?KEY$/i;function E(e){return A.includes(e)||oe.test(e)}function k(e){return e&&(e.length>=16?`${e.slice(0,5)}\u2026\u2022\u2022\u2022\u2022 (hidden)`:"\u2022\u2022\u2022\u2022 (hidden)")}function ue(e){let s;for(let[a,t]of Object.entries(e))typeof t=="string"&&t&&E(a)&&(s??(s={...e}),s[a]=k(t));return s??e}o();function le(){let e=r.getAccessToken();if(e)return{token:e,origin:r.origin};let s=n.getState().licenseKey;return s&&p(s)&&n.hasAccountAccess()&&d(s).ok?{token:s,origin:r.origin}:null}function ge(e){return e.startsWith("app:")?e.slice(4)||null:/^https?:\/\//.test(e)?e:null}function pe(){let e=r.getAccessToken();if(e){let t=r.getStatus(),i=t.state==="active"?t.claims:null;return i?.team?{token:e,origin:r.origin,team:i.team,appId:ge(i.aud)}:null}let s=n.getState().licenseKey;if(!s||!p(s)||!n.hasAccountAccess())return null;let a=d(s);return!a.ok||!a.claims.team?null:{token:s,origin:r.origin,team:a.claims.team,appId:null}}async function fe(e){let{LicenseManager:s}=await import("./chunks/LicenseManager-KXCX4GG2.mjs");return await s.initialize(),s.setLicenseKey(e)}function S(){return m(n.hasAccountAccess(),l())}function me(){return n.isPro()?true:S()}function de(e){return n.hasEntitlement(e)?true:S()}export{A as BUOY_ACCOUNT_KEY_NAMES,n as LicenseManager,M as LicenseTransportError,X as SessionError,r as SessionManager,v as callCapacitorAsApp,b as callCapacitorNative,T as callCapacitorNativeCallback,J as capacitorDebug,Y as capacitorListenerCount,G as capacitorPlatform,D as capacitorPlugin,w as clearCapacitorCalls,h as colorSchemeQueryValue,I as emitCapacitorEvent,j as getCapacitorAppHost,N as getCapacitorCalls,L as getColorSchemeQueries,le as getSyncCredential,pe as getTeamCredential,O as hasCapacitorPlugin,de as hasEntitlement,K as installCapacitorBridge,B as interceptCapacitor,E as isBuoyAccountKeyName,H as isBuoyToken,P as isCapacitorBridgeInstalled,R as isCapacitorNative,p as isDevToken,me as isPro,$ as isServiceKey,V as isTransientLicenseError,l as isWeekendFreePro,U as listenCapacitorNative,W as loadCapacitorAppHost,_ as makeCapacitorCallbackId,k as maskBuoyAccountKey,ue as maskBuoyAccountKeys,q as normalizeLicenseKey,Q as resolveAccountAccess,Z as resolveDevBuild,x as sameLicenseKey,fe as setLicenseKey,z as subscribeCapacitorCalls,te as useAccountAccess,ce as useBuoySession,ie as useFeatureAccess,ne as useIsPro,c as useLicense,re as useProAccess,ae as useTier,f as useWeekendFreePro};/*!
|
|
2
2
|
* PROPRIETARY — Buoy Pro license enforcement. NOT open source.
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use client";import{m as e}from"./chunk-7T66ARUE.mjs";import"./chunk-J7MW3NXU.mjs";export{e as LicenseManager};
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
"use client";import{a as p,d as be}from"./chunk-J7MW3NXU.mjs";var L=new Map,xe={async getItem(e){try{return localStorage.getItem(e)??L.get(e)??null}catch{return L.get(e)??null}},async setItem(e,t){L.set(e,t);try{localStorage.setItem(e,t)}catch{}},async removeItem(e){L.delete(e);try{localStorage.removeItem(e)}catch{}}};async function w(){return xe}var Le="3b546fc717a62683f3236c70167899a271bee3ffc04df6ec1eea60a394a2f1e9";var Ie="36abba0267f7f379d992a5b6df641daab4190bcc9e639e36f1378e3c1ac52746";var I=Object.freeze({accountId:"b0eba0e8-e904-4906-b644-38f9aab57bed",productId:"bf67cb43-eeef-40ca-b308-e6e1b22c0eaa",apiUrl:"https://buoy.gg/api/license"}),R=Object.freeze({free:"394e3351-1249-4f73-807a-703408604c0e",solo:"fa5d3c8f-5379-40f1-b63e-ab8a974b2f28",business:"690c2212-8e54-426f-b4b4-002ee1c0ae2b"}),N=720*60*60*1e3,Re=1440*60*1e3,M="buoy-gg-license",V="buoy-gg-device-fingerprint",q="buoy-gg-device-fingerprint-owner",Ne=3600*1e3,Ce=[5*1e3,20*1e3,60*1e3,300*1e3,900*1e3],Se=60*1e3,Z=3600*1e3,Pe=1440*60*1e3,Ke=50,Oe=N,D="buoy-gg-license-hold";function h(){let e=globalThis.__buoyRealNow;return typeof e=="function"?e():Date.now()}var{apiUrl:Q}=I,A=class extends Error{constructor(e,t,i=null){super(e);this.isTransient=true;this.name="LicenseTransportError",this.status=t,this.retryAfterMs=i}};function Me(e){let t=e?.status;return t===429||t===402}function Ve(e,t,i){return e.status===402?t:e.retryAfterMs??i}function De(e){let t=s=>{try{return e.headers?.get?.(s)??null}catch{return null}},i=t("Retry-After");if(i){let s=Number(i);if(Number.isFinite(s)&&s>=0)return s*1e3;let n=Date.parse(i);if(Number.isFinite(n))return Math.max(0,n-h())}let r=Number(t("X-RateLimit-Reset"));return Number.isFinite(r)&&r>0?Math.max(0,r*1e3-h()):null}function ee(e){return e instanceof A||e instanceof TypeError?true:typeof e=="object"&&e!==null&&e.isTransient===true}async function Ue(e){try{return(await e.json()).errors?.[0]?.detail||`HTTP ${e.status}`}catch{return`HTTP ${e.status}`}}function te(){return{"Content-Type":"application/vnd.api+json",Accept:"application/vnd.api+json"}}async function Fe(e,t){let i=`${Q}/validate`,r={meta:{key:e}},s;try{s=await fetch(i,{signal:t,method:"POST",headers:te(),body:JSON.stringify(r)})}catch(n){throw new A(n instanceof Error?n.message:"Network request failed",null)}if(!s.ok)throw new A(await Ue(s),s.status,s.status===429?De(s):null);try{let n=await s.json();if(!n||typeof n!="object"||typeof n.meta?.valid!="boolean"||typeof n.meta?.code!="string"||!n.meta.code)throw new Error("Missing license verdict");return n}catch{throw new A("License server returned an unreadable response",s.status)}}async function $e(e){let t=typeof AbortController=="function"?new AbortController:null,i;try{return await Promise.race([Fe(e,t?.signal),new Promise((r,s)=>{i=setTimeout(()=>{s(new A("License verification timed out. Please retry.",null)),t?.abort()},15e3)})])}finally{i&&clearTimeout(i)}}function je(e){if(!e.data)return false;let t=e.data.relationships?.product?.data?.id;return t&&t!==I.productId?false:e.meta.valid&&e.meta.code==="VALID"?true:["OVERDUE","NO_MACHINE","NO_MACHINES","TOO_MANY_MACHINES","TOO_MANY_CORES","TOO_MANY_PROCESSES","FINGERPRINT_SCOPE_MISMATCH","HEARTBEAT_NOT_STARTED","HEARTBEAT_DEAD"].includes(e.meta.code)}function Be(e){let t=e.data?.relationships?.machines?.meta?.count;return typeof t=="number"&&Number.isFinite(t)?t:0}async function ie(e,t,i,r,s){let n=`${Q}/machines`,c=await fetch(n,{method:"POST",headers:te(),body:JSON.stringify({licenseId:e,licenseKey:t,fingerprint:i,name:r,metadata:s||{}})});if(!c.ok){let o=await c.json(),a=o.errors?.[0]?.code;if(a==="FINGERPRINT_TAKEN")throw new Error("FINGERPRINT_TAKEN");if(a==="MACHINE_LIMIT_EXCEEDED")throw new Error("MACHINE_LIMIT_EXCEEDED");let l=o.errors?.[0]?.detail||`HTTP ${c.status}`;throw new Error(l)}return c.json()}function He(e){let{meta:t,data:i}=e;return{valid:t.valid,code:t.code,detail:t.detail,metadata:i?.attributes?.metadata}}function ze(e){return["NOT_FOUND","SUSPENDED","EXPIRED","BANNED","PRODUCT_SCOPE_MISMATCH"].includes(e)}function U(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}function F(){let e=be();if(e!==null)return e;if(typeof p<"u")return p;try{if(typeof navigator<"u"&&/electron/i.test(navigator.userAgent))return true}catch{}return typeof process<"u"&&process.env.NODE_ENV!=="production"}function re(){if(typeof navigator>"u")return"unknown";let e=navigator.userAgent.toLowerCase(),t=navigator.platform?.toLowerCase()||"";return e.includes("electron")?t.includes("mac")||e.includes("mac")?"electron-macos":t.includes("win")||e.includes("win")?"electron-windows":t.includes("linux")||e.includes("linux")?"electron-linux":"electron":t.includes("mac")||e.includes("mac")?"macos":t.includes("win")||e.includes("win")?"windows":t.includes("linux")||e.includes("linux")?"linux":/iphone|ipad|ipod/.test(e)?"ios-web":e.includes("android")?"android-web":"web"}function Ge(){if(typeof navigator>"u")return"unknown";let e=navigator.userAgent,t=e.match(/Mac OS X ([\d_.]+)/);if(t)return t[1].replace(/_/g,".");let i=e.match(/Windows NT ([\d.]+)/);return i?{"10.0":"10/11","6.3":"8.1","6.2":"8","6.1":"7"}[i[1]]||i[1]:e.includes("Linux")?"Linux":"unknown"}function se(){if(typeof navigator>"u")return{name:"unknown",version:"unknown"};let e=navigator.userAgent,t=e.match(/Electron\/([\d.]+)/);if(t)return{name:"Electron",version:t[1]};let i=e.match(/Chrome\/([\d.]+)/);if(i&&!e.includes("Edg"))return{name:"Chrome",version:i[1]};let r=e.match(/Edg\/([\d.]+)/);if(r)return{name:"Edge",version:r[1]};let s=e.match(/Firefox\/([\d.]+)/);if(s)return{name:"Firefox",version:s[1]};let n=e.match(/Version\/([\d.]+).*Safari/);return n?{name:"Safari",version:n[1]}:{name:"unknown",version:"unknown"}}function ne(){let e={platform:re(),osVersion:Ge(),isSimulator:"false"},t=se();e.browser=t.name,e.browserVersion=t.version,typeof window<"u"&&window.screen&&(e.screenResolution=`${window.screen.width}x${window.screen.height}`),typeof navigator<"u"&&navigator.language&&(e.language=navigator.language);try{e.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone}catch{}return e}function $(){let e=re(),t=se();if(e.startsWith("electron")){let i=e.replace("electron-","").replace("electron","Desktop");return`${i.charAt(0).toUpperCase()+i.slice(1)} App`}return t.name!=="unknown"?`${t.name} Browser`:"Web Browser"}async function Je(){return null}function Ye(e){let{stored:t,storedOwner:i,marker:r,blobFingerprint:s,mint:n}=e;if(!!r&&!!i&&i!==r)return{fingerprint:n(),owner:r,restored:true,changed:true};let c=r??i;return t?{fingerprint:t,owner:c,restored:false,changed:c!==i}:{fingerprint:s||n(),owner:c,restored:false,changed:true}}function Xe(e){let t=2166136261,i=16777619;for(let r=0;r<e.length;r++){let s=e.charCodeAt(r);t=Math.imul(t^s,16777619)>>>0,i=Math.imul(i^s,1540483477)>>>0}return`v1:${t.toString(16).padStart(8,"0")}${i.toString(16).padStart(8,"0")}`}var We=["v1"],qe="buoy.gg/pro:9f3c1d7a4b2e:license-cache";function ae(e,t){let i=t>>>0;for(let r=0;r<e.length;r++)i^=e.charCodeAt(r),i=Math.imul(i,16777619)>>>0;return i>>>0}function Ze(e,t){let i=[t,e.licenseKey,e.licenseId,e.isPro?"1":"0",e.expiresAt??"",String(e.cachedAt)];return t!=="v1"&&i.push(e.tier??""),i.push(qe),i.join("\0")}function oe(e,t){let i=Ze(e,t),r=ae(i,2166136261),s=ae(i,2135587861);return`${t}.${r.toString(16)}${s.toString(16)}`}function le(e){return oe(e,"v2")}function ce(e){return{...e,sig:le(e)}}function _(e){return!e||typeof e.sig!="string"||e.sig.length===0?false:e.sig===le(e)?true:We.some(t=>e.sig.startsWith(`${t}.`)&&e.sig===oe(e,t))}import Qe from"tweetnacl";var et=1,tt=1,it="buoy-free-token-v1:",rt=22,st=64,he=/^BUOY1-([A-Z2-7]+)-([A-Z2-7]+)$/;function ue(e){return he.test(e.trim().toUpperCase())}var nt="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";function de(e){let t=[],i=0,r=0;for(let s of e){let n=nt.indexOf(s);if(n===-1)return null;r=r<<5|n,i+=5,i>=8&&(t.push(r>>>i-8&255),i-=8)}return new Uint8Array(t)}function at(e){let t=e.trim().toLowerCase(),i=new Uint8Array(t.length/2);for(let r=0;r<i.length;r+=1)i[r]=parseInt(t.slice(r*2,r*2+2),16);return i}function ot(e){let t="";for(let i of e)t+=i.toString(16).padStart(2,"0");return t}function lt(e){if(typeof TextEncoder<"u")return new TextEncoder().encode(e);let t=new Uint8Array(e.length);for(let i=0;i<e.length;i+=1)t[i]=e.charCodeAt(i)&255;return t}function ct(e,t){let i=new Uint8Array(e.length+t.length);return i.set(e,0),i.set(t,e.length),i}function ht(e){return ct(lt(it),e)}var ut=Le;function dt(e){let t=he.exec(e.trim().toUpperCase());if(!t)return null;let i=de(t[1]),r=de(t[2]);if(!i||!r||i.length!==rt||r.length!==st||i[0]!==et||i[1]!==tt)return null;try{if(!Qe.sign.detached.verify(ht(i),r,at(ut)))return null}catch{return null}return{tier:"free",issuedAt:((i[2]<<24>>>0)+(i[3]<<16)+(i[4]<<8)+i[5])*1e3,accountHash:ot(i.slice(6,22))}}function ft(e){let t=e.relationships?.policy?.data?.id;return t===R.free?"free":t===R.solo||t===R.business?"pro":e.attributes?.metadata?.plan==="free"?"free":"pro"}function pt(e){if(!e)return false;let t=e.relationships?.product?.data?.id;if(t)return t===I.productId;let i=e.relationships?.policy?.data?.id;return Object.values(R).some(r=>r===i)}function fe(e,t=h()){let i=e.verifiedAt!==null&&Number.isFinite(e.verifiedAt)&&e.verifiedAt<=t?e.verifiedAt+N:null;return e.initialized&&e.key&&e.tierSource!=="none"&&i!==null&&t<i?{status:"admitted",reason:null,validUntil:i}:i!==null&&t>=i?{status:"locked",reason:"verification_expired",validUntil:i}:!e.initialized||e.validating?{status:"initializing",reason:"checking",validUntil:i}:{status:"locked",reason:i!==null&&t>=i?"verification_expired":"account_required",validUntil:i}}function gt(e){if(typeof window>"u"||typeof window.addEventListener!="function")return()=>{};let t=()=>{document.hidden||e()};return window.addEventListener("focus",e),document.addEventListener("visibilitychange",t),()=>{window.removeEventListener("focus",e),document.removeEventListener("visibilitychange",t)}}import mt from"tweetnacl";var pe="buoys1",yt="buoy-session-v1:",ge=1,j=60,wt=64,vt=["free","pro","business"],m="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";function B(e){let t="",i=0;for(;i+2<e.length;i+=3){let s=e[i]<<16|e[i+1]<<8|e[i+2];t+=m[s>>>18&63]+m[s>>>12&63]+m[s>>>6&63]+m[s&63]}let r=e.length-i;if(r===1){let s=e[i]<<16;t+=m[s>>>18&63]+m[s>>>12&63]}else if(r===2){let s=e[i]<<16|e[i+1]<<8;t+=m[s>>>18&63]+m[s>>>12&63]+m[s>>>6&63]}return t}function me(e){if(!/^[A-Za-z0-9_-]*$/.test(e)||e.length%4===1)return null;let t=[],i=0,r=0;for(let s of e)r=r<<6|m.indexOf(s),i+=6,i>=8&&(t.push(r>>>i-8&255),i-=8);return new Uint8Array(t)}function Tt(e){if(typeof TextEncoder<"u")return new TextEncoder().encode(e);let t=unescape(encodeURIComponent(e)),i=new Uint8Array(t.length);for(let r=0;r<t.length;r+=1)i[r]=t.charCodeAt(r);return i}function At(e){try{if(typeof TextDecoder<"u")return new TextDecoder("utf-8",{fatal:true}).decode(e);let t="";for(let i of e)t+=String.fromCharCode(i);return decodeURIComponent(escape(t))}catch{return null}}function _t(e){let t=e.trim().toLowerCase(),i=new Uint8Array(t.length/2);for(let r=0;r<i.length;r+=1)i[r]=parseInt(t.slice(r*2,r*2+2),16);return i}function kt(e){return Tt(yt+e)}function k(e,t=256){return typeof e=="string"&&e.length>0&&e.length<=t}function ye(e){return typeof e=="number"&&Number.isInteger(e)&&e>0}function Et(e){if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e;return!k(t.sid)||!k(t.sub)||!k(t.aud,512)||t.team!==null&&!k(t.team)||!vt.includes(t.tier)||t.role!==void 0&&!k(t.role,64)||t.tools!==void 0&&(!Array.isArray(t.tools)||t.tools.length>256||!t.tools.every(i=>k(i,64)))||!ye(t.iat)||!ye(t.exp)||t.exp<=t.iat?null:{v:ge,sid:t.sid,sub:t.sub,team:t.team,tier:t.tier,...t.role!==void 0?{role:t.role}:{},...t.tools!==void 0?{tools:[...t.tools]}:{},aud:t.aud,iat:t.iat,exp:t.exp}}var bt=Ie;function we(e){return e.startsWith(`${pe}.`)}function H(e,t){let i=bt;if(!i)return{ok:false,reason:"no-key"};let r=typeof e=="string"?e.split("."):[];if(r.length!==3||r[0]!==pe)return{ok:false,reason:"malformed"};let[,s,n]=r,c=me(s),o=me(n);if(!c||!o||o.length!==wt)return{ok:false,reason:"malformed"};try{if(!mt.sign.detached.verify(kt(s),o,_t(i)))return{ok:false,reason:"signature"}}catch{return{ok:false,reason:"signature"}}let a=At(c),l;try{l=a===null?null:JSON.parse(a)}catch{return{ok:false,reason:"malformed"}}if(!l||typeof l!="object"||l.v!==ge)return{ok:false,reason:l&&typeof l=="object"?"version":"malformed"};let u=Et(l);if(!u)return{ok:false,reason:"claims"};if(u.aud!==t.audience)return{ok:false,reason:"audience"};if(t.ignoreTime)return{ok:true,claims:u};let f=Math.floor((t.nowMs??h())/1e3);return f>=u.exp+j?{ok:false,reason:"expired"}:u.iat>f+j?{ok:false,reason:"not-yet-valid"}:{ok:true,claims:u}}var xt="@buoy/session:",C=10080*60*1e3,ve=360*60*1e3,Lt=300*1e3,It=15e3,Rt="https://buoy.gg",Nt="buoy:signin",Ct=600*1e3,d=class extends Error{constructor(e,t){super(t);this.code=e;this.name="SessionError"}};function St(){let e=globalThis;return{fetch:(t,i)=>fetch(t,i),storage:w,now:h,random:t=>{let i=new Uint8Array(t);if(!e.crypto?.getRandomValues)throw new d("not_configured","This platform has no secure random source.");return e.crypto.getRandomValues(i)},sha256:async t=>{if(!e.crypto?.subtle)throw new d("not_configured","Sign-in needs a secure page (https or localhost).");return new Uint8Array(await e.crypto.subtle.digest("SHA-256",t))},openPopup:()=>{if(!e.window?.open)return null;let t=480,i=640,r=Math.max(0,(e.window.screenX??0)+((e.window.outerWidth??t)-t)/2),s=Math.max(0,(e.window.screenY??0)+((e.window.outerHeight??i)-i)/2);return e.window.open("about:blank","buoy-signin",`popup,width=${t},height=${i},left=${r},top=${s}`)},onMessage:t=>{if(!e.window?.addEventListener)return()=>{};let i=r=>t({origin:r.origin,data:r.data});return e.window.addEventListener("message",i),()=>e.window?.removeEventListener("message",i)},withLock:(t,i)=>e.navigator?.locks?e.navigator.locks.request(t,i):i(),watch:t=>{let i=e.window;if(!i?.addEventListener)return()=>{};let r=n=>t.storage(n.key),s=()=>{i.document?.visibilityState!=="hidden"&&t.wake()};return i.addEventListener("storage",r),i.addEventListener("online",t.wake),i.document?.addEventListener?.("visibilitychange",s),()=>{i.removeEventListener("storage",r),i.removeEventListener("online",t.wake),i.document?.removeEventListener?.("visibilitychange",s)}},setTimer:(t,i)=>setTimeout(t,Math.min(i,2147483647)),clearTimer:t=>clearTimeout(t)}}function Pt(){let e=globalThis.location;if(!(!e?.origin||!/^https?:$/.test(e.protocol??"")))return e.origin}var Kt=class{constructor(e){this.signinOrigin=Rt;this.current=null;this.claims=null;this.listeners=new Set;this.timer=null;this.refreshing=null;this.loaded=null;this.unwatch=null;this.limitTimer=null;this.epoch=0;this.deps=e??St(),this.audience=Pt()}get origin(){return this.signinOrigin}configure(e){e.audience!==void 0&&(this.audience=e.audience),e.signinOrigin!==void 0&&(this.signinOrigin=e.signinOrigin.replace(/\/$/,"")),this.reset()}reset(){this.unwatch?.(),this.unwatch=null,this.epoch+=1,this.limitTimer!==null&&this.deps.clearTimer(this.limitTimer),this.limitTimer=null,this.timer!==null&&this.deps.clearTimer(this.timer),this.timer=null,this.current=null,this.claims=null,this.loaded=null,this.refreshing=null}get storageKey(){return xt+(this.audience??"")}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}notify(){for(let e of[...this.listeners])try{e()}catch(t){console.warn("[Buoy] sign-in listener error:",t)}}getAccessToken(){let e=this.getStatus();return e.state==="active"&&!e.grace?this.current?.accessToken??null:null}getStatus(){let e=this.claims;if(!e)return{state:"signed_out"};let t=e.exp*1e3,i=this.deps.now();return i<(e.iat-j)*1e3?{state:"signed_out"}:i<t?{state:"active",claims:e,grace:false,validUntil:t}:i<t+C?{state:"active",claims:e,grace:true,validUntil:t+C}:{state:"signed_out"}}load(){return this.loaded||(this.loaded=this.loadOnce()),this.loaded}async loadOnce(){if(!this.audience)return;this.unwatch??(this.unwatch=this.deps.watch?.({storage:t=>{(t===null||t===this.storageKey)&&this.sync()},wake:()=>{this.claims&&this.refresh()}})??null);let e=await this.read();e&&this.adopt(e)&&(this.notify(),this.schedule())}async sync(){if(!this.audience)return;let e=await this.read();if(!e){this.current&&this.clearLocal();return}e.refreshToken!==this.current?.refreshToken&&this.adopt(e)&&(this.notify(),this.schedule())}async read(){try{let e=await(await this.deps.storage()).getItem(this.storageKey);if(!e)return null;let t=JSON.parse(e);return t?.v===1&&typeof t.accessToken=="string"&&typeof t.refreshToken=="string"?t:null}catch{return null}}async write(e){let t=await this.deps.storage();e?await t.setItem(this.storageKey,JSON.stringify(e)):await t.removeItem(this.storageKey)}adopt(e){if(!this.audience)return false;let t=H(e.accessToken,{audience:this.audience,ignoreTime:true}),i=t.ok?t.claims:null;return i?(this.current=e,this.claims=i,true):false}armLimit(){if(this.limitTimer!==null&&this.deps.clearTimer(this.limitTimer),this.limitTimer=null,!this.claims)return;let e=this.claims.exp*1e3,t=this.deps.now(),i=t<e?e:t<e+C?e+C:null;i!==null&&(this.limitTimer=this.deps.setTimer(()=>{this.limitTimer=null,this.notify(),this.armLimit()},i-t))}call(e,t){return new Promise((i,r)=>{let s=this.deps.setTimer(()=>r(new Error("timeout")),It);this.deps.fetch(e,t).then(n=>{this.deps.clearTimer(s),i(n)},n=>{this.deps.clearTimer(s),r(n)})})}schedule(){if(this.armLimit(),this.timer!==null&&this.deps.clearTimer(this.timer),this.timer=null,!this.claims)return;let e=this.claims.exp*1e3-ve-this.deps.now();this.timer=this.deps.setTimer(()=>{this.timer=null,this.refresh()},Math.max(0,e))}refresh(e=false){return this.refreshing||(this.refreshing=this.deps.withLock(this.lockName,()=>this.refreshLocked(e)).catch(()=>this.retryLater()).finally(()=>{this.refreshing=null})),this.refreshing}get lockName(){return`buoy-session:${this.audience??""}`}async refreshLocked(e){let t=this.epoch,i=await this.read();if(!i){this.current&&this.clearLocal();return}if(i.refreshToken!==this.current?.refreshToken&&this.adopt(i)){this.notify(),this.schedule();return}if(!this.claims)return;if(!e&&this.claims.exp*1e3-this.deps.now()>ve){this.schedule();return}let r,s;try{let n=await this.call(`${this.signinOrigin}/api/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refresh_token:i.refreshToken,audience:this.audience})});r=n.status,s=await n.json().catch(()=>null)}catch{this.retryLater();return}if(t===this.epoch){if(r===200&&s&&typeof s.access_token=="string"&&typeof s.refresh_token=="string"){let n={v:1,accessToken:s.access_token,refreshToken:s.refresh_token};if(this.adopt(n)){await this.write(n),this.notify(),this.schedule();return}}if(r===400||r===401||r===403){await this.write(null),this.clearLocal();return}this.retryLater()}}retryLater(){this.armLimit(),this.timer!==null&&this.deps.clearTimer(this.timer),this.timer=this.deps.setTimer(()=>{this.timer=null,this.refresh(true)},Lt),this.notify()}clearLocal(){this.timer!==null&&this.deps.clearTimer(this.timer),this.timer=null,this.limitTimer!==null&&this.deps.clearTimer(this.limitTimer),this.limitTimer=null,this.current=null,this.claims=null,this.notify()}async signIn(){if(!this.audience)throw new d("not_configured","Sign-in needs a web page or a configured app id.");let e=this.deps.openPopup();if(!e)throw new d("popup_blocked","The browser blocked the sign-in window. Allow pop-ups for this site and try again.");try{return await this.signInWith((t,i)=>new Promise((r,s)=>{e.location.href=t;let n=this.deps.now(),c=null,o=u=>{c!==null&&this.deps.clearTimer(c),a(),u()},a=this.deps.onMessage(u=>{if(u.origin!==this.signinOrigin)return;let f=u.data;!f||f.type!==Nt||f.state!==i||(typeof f.code=="string"?o(()=>r(f.code)):o(()=>s(new d("access_denied","Sign-in was cancelled."))))}),l=()=>{if(e.closed)return o(()=>s(new d("popup_closed","The sign-in window was closed.")));if(this.deps.now()-n>Ct)return o(()=>s(new d("timeout","Sign-in took too long.")));c=this.deps.setTimer(l,500)};c=this.deps.setTimer(l,500)}))}finally{try{e.closed||e.close()}catch{}}}async signInWith(e){let t=this.audience;if(!t)throw new d("not_configured","Sign-in needs a web page or a configured app id.");let i=B(this.deps.random(32)),r=B(this.deps.random(16)),s=B(await this.deps.sha256(new TextEncoder().encode(i))),n=`${this.signinOrigin}/auth/authorize?audience=${encodeURIComponent(t)}&code_challenge=${s}&code_challenge_method=S256&state=${r}`,c=await e(n,r),o;try{o=await this.call(`${this.signinOrigin}/api/auth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:c,code_verifier:i,audience:t})})}catch{throw new d("network","Buoy could not be reached. Check your connection and try again.")}let a=await o.json().catch(()=>null);if(o.status!==200||!a||typeof a.access_token!="string"||typeof a.refresh_token!="string"){let l=a&&typeof a.error_description=="string"?a.error_description:"Buoy did not accept this sign-in.";throw new d(o.status===503?"unavailable":"rejected",l)}return this.finishSignIn(a.access_token,a.refresh_token)}async finishSignIn(e,t){let i={v:1,accessToken:e,refreshToken:t};if(this.epoch+=1,!this.adopt(i))throw new d("rejected","Buoy sent a sign-in this app could not check.");return await this.write(i),await this.load(),this.notify(),this.schedule(),this.getStatus()}async signInWithCode(e,t={}){let i=this.audience;if(!i)throw new d("not_configured","Sign-in with a code needs this app's id (app:com.example.app).");let r=(a,l)=>this.call(`${this.signinOrigin}/api/auth/device/${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(l)}),s;try{s=await r("start",{audience:i})}catch{throw new d("network","Buoy could not be reached. Check your connection and try again.")}let n=await s.json().catch(()=>null);if(s.status!==200||!n||typeof n.device_code!="string"||typeof n.user_code!="string"||typeof n.verification_uri!="string"||typeof n.verification_uri_complete!="string"){let a=n&&typeof n.error_description=="string"?n.error_description:"Buoy could not start a sign-in.";throw new d(s.status===503?"unavailable":"rejected",a)}let c=this.deps.now()+(Number(n.expires_in)||600)*1e3,o=Math.max(5,Number(n.interval)||5)*1e3;for(e({userCode:n.user_code,verificationUri:n.verification_uri,verificationUriComplete:n.verification_uri_complete,expiresAt:c});;){if(await this.wait(o,t.signal),this.deps.now()>c)throw new d("timeout","The code ran out. Start again for a new one.");let a;try{a=await r("poll",{device_code:n.device_code})}catch{continue}let l=await a.json().catch(()=>null);if(a.status===200&&l&&typeof l.access_token=="string"&&typeof l.refresh_token=="string")return this.finishSignIn(l.access_token,l.refresh_token);let u=l&&typeof l.error=="string"?l.error:"";if(u==="authorization_pending"||a.status>=500)continue;if(u==="slow_down"||a.status===429){o+=5e3;continue}if(u==="access_denied")throw new d("access_denied","The sign-in was turned down on buoy.gg.");if(u==="expired_token")throw new d("timeout","The code ran out. Start again for a new one.");let f=l&&typeof l.error_description=="string"?l.error_description:"Buoy did not accept this sign-in.";throw new d("rejected",f)}}wait(e,t){return new Promise((i,r)=>{let s=()=>new d("access_denied","Sign-in was cancelled.");if(t?.aborted)return r(s());let n=()=>{this.deps.clearTimer(c),r(s())},c=this.deps.setTimer(()=>{t?.removeEventListener?.("abort",n),i()},e);t?.addEventListener?.("abort",n)})}async signOut(){this.epoch+=1;let e=this.current;this.clearLocal();let t=e;try{await this.deps.withLock(this.lockName,async()=>{t=await this.read()??e,await this.write(null)})}catch{await this.write(null).catch(()=>{})}if(t)try{await this.call(`${this.signinOrigin}/api/auth/revoke`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refresh_token:t.refreshToken})})}catch{}}},v=new Kt;var Ot="bsk1_",Mt="service",Vt=15e3;function z(e){return e.startsWith(Ot)}function b(e){let t=e.trim();return z(t)||we(t)?t:t.toUpperCase()}function Dt(e,t){return b(e??"")===b(t??"")}async function Ut(e,t){let i=t.fetch??((a,l)=>fetch(a,l)),r=typeof AbortController<"u"?new AbortController:void 0,s=setTimeout(()=>r?.abort(),Vt),n,c;try{let a=await i(`${t.origin.replace(/\/$/,"")}/api/auth/service-token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({key:e}),signal:r?.signal});n=a.status,c=await a.json().catch(()=>null)}catch{return{ok:false,reason:"network",detail:"Buoy could not be reached to check the bot key."}}finally{clearTimeout(s)}if(n>=500||n===429)return{ok:false,reason:"network",detail:"Buoy is busy. The bot key will be checked again soon."};if(n!==200||typeof c?.access_token!="string")return{ok:false,reason:"rejected",detail:typeof c?.error_description=="string"?c.error_description:"This bot key was not accepted."};let o=H(c.access_token,{audience:Mt,nowMs:h()});return o.ok?{ok:true,claims:o.claims}:{ok:false,reason:"rejected",detail:"Buoy sent a token this app could not check."}}var Ft="dev";function Te(e){return we(e)}function Ae(e,t=h()){let i=H(e,{audience:Ft,ignoreTime:true});return i.ok?t>=i.claims.exp*1e3?{ok:false,reason:"expired",message:"Your dev token ran out. Run `npx --package=@buoy-gg/core buoy login` again."}:{ok:true,claims:i.claims}:{ok:false,reason:"invalid",message:"This dev token is not valid. Run `npx --package=@buoy-gg/core buoy login` again."}}var $t="This is a dev token. It only works in dev builds. A live build turns on Buoy with Sign in with Buoy.";var jt={role:null,tools:null};function _e(e){return{role:e.role??null,tools:e.tools??null}}async function y(e,t){let i;try{return await Promise.race([e,new Promise(r=>{i=setTimeout(()=>r(t),15e3)})])}finally{i&&clearTimeout(i)}}function E(e){return e.tier==="pro"||e.tier==="free"?e.tier:e.isPro?"pro":"free"}var Bt=class{constructor(){this.state={isInitialized:false,isValidating:false,isPro:false,tier:"free",tierSource:"none",licenseKey:null,error:null,errorKind:null,expiresAt:null};this.listeners=new Set;this.revalidationTimer=null;this.cachedLicense=null;this.fingerprintPromise=null;this.fingerprintRestored=false;this.initPromise=null;this.generation=0;this.persistence=Promise.resolve();this.verifiedAt=null;this.expiryTimer=null;this.removeForegroundListener=null;this.sessionUnsubscribe=null;this.devToken=null;this.retryTimer=null;this.retryAttempt=0;this.deviceRegistrationCallback=null;this.pendingRegistration=null}async initialize(){if(this.initPromise)return this.initPromise;if(!this.state.isInitialized)return this.initPromise=this._doInitialize(),this.initPromise}async _doInitialize(){if(this.state.isInitialized)return;let e=this.generation;this.sessionUnsubscribe||(this.sessionUnsubscribe=v.subscribe(()=>this.emit({type:"validated",isPro:this.isPro()}))),await y(v.load().catch(()=>{}),void 0);try{let t=await y(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)){let i=_(t);this.cachedLicense=t,this.state.licenseKey=t.licenseKey,i&&this.isCacheValid(t)?this.applyTier(E(t)):this.lock(),this.state.expiresAt=t.expiresAt?new Date(t.expiresAt):null,i&&this.isCacheValid(t)&&this.setVerifiedAt(t.cachedAt),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("[Buoy]","[React Buoy] License initialization failed:",t),this.state.isInitialized=true,this.emit({type:"initialized",isPro:false})}}async configure(e){if(e===void 0)return await this.initialize(),this.hasAccountAccess();let t=b(e),i=++this.generation;return this.cancelRetry(),this.configuredKey=t||null,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(),i!==this.generation?false:t?this.setLicenseKey(t):(await this.clearLicense(),false)}async setLicenseKey(e,t){if(!e||e.trim().length===0)return this.state.error="License key is required",this.state.errorKind="verdict",false;let i=b(e),r=++this.generation;if(this.cancelRetry(),t?.isRetry||(this.retryAttempt=0),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()}),ue(i))return this.admitToken(i,r);if(z(i))return this.admitServiceKey(i,r);if(Te(i))return this.admitDevToken(i);if(!this.cachedLicense){let a=await y(this.loadCachedLicense(),null);if(r!==this.generation)return false;a?.licenseKey===i&&(this.cachedLicense=a,_(a)&&this.isCacheValid(a)&&(this.applyTier(E(a)),this.state.expiresAt=a.expiresAt?new Date(a.expiresAt):null,this.setVerifiedAt(a.cachedAt),this.emit({type:"validating",isPro:this.isPro()})))}let s=this.cachedLicense;if(!t?.force&&s&&s.valid&&s.licenseKey===i&&s.fingerprint&&_(s)&&this.isCacheValid(s)&&this.isCacheFresh(s))return this.applyTier(E(s)),this.state.licenseKey=i,this.state.isValidating=false,this.state.error=null,this.state.errorKind=null,this.state.expiresAt=s.expiresAt?new Date(s.expiresAt):null,this.setVerifiedAt(s.cachedAt),this.emit({type:"validated",isPro:this.state.isPro}),true;let n=await y(this.loadHold(),null);if(r!==this.generation)return false;let c=(n?.backoffUntil??0)-h();if(c>0)return this.standDown(i,r,"License server is rate limited; retrying later.",c);if(!t?.force&&n?.key===i&&n.verdictAt!==void 0&&h()-n.verdictAt>=0&&h()-n.verdictAt<Pe)return this.lock(),this.state.isValidating=false,this.state.error=n.detail||"License could not be verified",this.state.errorKind="verdict",this.emit({type:"error",isPro:false,error:this.state.error}),false;let o;try{o=await $e(i)}catch(a){let l=a instanceof Error?a.message:"Validation failed";if(r!==this.generation)return false;if(ee(a)){if(Me(a)){let u=Math.min(Ve(a,Z,Se)*2**this.retryAttempt,Z);return this.retryAttempt+=1,await this.saveHold({...this.hold,backoffUntil:h()+u}),r!==this.generation?false:this.standDown(i,r,l,u)}return this.state.isValidating=false,this.cachedLicense&&this.cachedLicense.licenseKey===i&&_(this.cachedLicense)&&this.isCacheValid(this.cachedLicense)?(this.applyTier(E(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),this.keyTier()!=="pro"&&this.scheduleRetry(i),this.emit({type:"validated",isPro:this.state.isPro}),true):(this.state.error=l,this.state.errorKind="transport",this.scheduleRetry(i),this.emit({type:"error",isPro:this.state.isPro,error:l}),false)}return this.state.isValidating=false,this.state.error=l,this.state.errorKind="verdict",this.emit({type:"error",isPro:false,error:l}),false}try{if(r!==this.generation)return false;let a=He(o),l=o.data?.relationships?.product?.data?.id;if((!l||l===I.productId)&&a.code==="EXPIRED"&&(pt(o.data)||this.cachedLicense?.licenseKey===i&&_(this.cachedLicense)&&this.isCacheValid(this.cachedLicense))){let O=h(),W=await this.saveCache({licenseKey:i,licenseId:o.data?.id??"",valid:true,isPro:false,tier:"free",expiresAt:null,cachedAt:O,lastValidatedAt:O,fingerprint:this.cachedLicense?.licenseKey===i?this.cachedLicense.fingerprint:void 0},r);return r!==this.generation||!W?false:(this.cachedLicense=W,this.applyTier("free"),this.state.isValidating=false,this.state.expiresAt=null,this.setVerifiedAt(O),this.emit({type:"validated",isPro:false}),true)}if(ze(a.code)||!je(o))return 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()}),false;if(!o.data)return 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(),false;let u=ft(o.data),f=o.data.id,S=h(),G=Be(o)>=Ke,J=F(),ke=J&&!G,Ee=u==="free"&&(G||!J),T=this.cachedLicense?.fingerprint,x=this.cachedLicense?.deviceName,Y=false;if(!T){if(T=await y(this.getOrCreateDeviceFingerprint(),U()),r!==this.generation)return false;x=$(),Y=ke}let P=false;Y&&(this.deviceRegistrationCallback?(this.pendingRegistration={licenseId:f,licenseKey:i,fingerprint:T},this.deviceRegistrationCallback({fingerprint:T,defaultName:x}),P=true):this.registerDeviceAsync(f,i,T,x));let K={licenseKey:i,licenseId:f,valid:true,isPro:u==="pro",tier:u,expiresAt:o.data.attributes.expiry??null,cachedAt:S,lastValidatedAt:S,fingerprint:P?void 0:T,deviceName:P?void 0:x,quiet:Ee||void 0},X=await this.saveCache(K,r);return r!==this.generation||!X||(this.cachedLicense=X,this.applyTier(u),this.state.isValidating=false,this.state.expiresAt=K.expiresAt?new Date(K.expiresAt):null,this.setVerifiedAt(S),this.hold&&await this.saveHold(null),r!==this.generation)?false:(this.retryAttempt=0,this.emit({type:"validated",isPro:this.state.isPro}),true)}catch(a){let l=a instanceof Error?a.message:"Validation failed";return r!==this.generation||(this.state.isValidating=false,this.state.error=l,this.state.errorKind="verdict",this.emit({type:"error",isPro:false,error:l})),false}}scheduleRetry(e){this.cancelRetry();let t=Ce[this.retryAttempt];if(t===void 0)return;this.retryAttempt+=1;let i=this.generation;this.retryTimer=setTimeout(()=>{this.retryTimer=null,i===this.generation&&(this.state.isValidating||this.setLicenseKey(e,{force:true,isRetry:true}))},t),typeof p<"u"&&p&&(globalThis.__LICENSE_MANAGER_RETRY_TIMER__=this.retryTimer)}async admitServiceKey(e,t){let i=await Ut(e,{origin:v.origin});if(t!==this.generation)return false;if(!i.ok)return this.lock(),this.state.isValidating=false,this.state.error=i.detail,this.state.errorKind=i.reason==="network"?"transport":"verdict",this.emit({type:"error",isPro:false,error:i.detail}),i.reason==="network"&&this.scheduleRetry(e),false;let r=i.claims.exp*1e3;return this.applyTier(i.claims.tier==="free"?"free":"pro"),this.state.isValidating=false,this.state.expiresAt=new Date(r),this.setVerifiedAt(h()),this.retryAttempt=0,this.scheduleRetryIn(e,Math.max(6e4,r-3600*1e3-h())),this.emit({type:"validated",isPro:this.isPro()}),true}admitDevToken(e){let t=Ae(e);if(!t.ok||!F()){let r=t.ok?$t:t.message;return this.lock(),this.state.isValidating=false,this.state.error=r,this.state.errorKind="verdict",this.emit({type:"error",isPro:false,error:r}),false}let i=h();return this.devToken={token:e,claims:t.claims},this.applyTier(t.claims.tier==="free"?"free":"pro"),this.state.isValidating=false,this.state.expiresAt=new Date(t.claims.exp*1e3),this.setVerifiedAt(Math.min(i,t.claims.iat*1e3)),this.retryAttempt=0,this.emit({type:"validated",isPro:this.isPro()}),true}async admitToken(e,t){let i=dt(e);if(t!==this.generation)return false;if(!i)return 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(),false;let r=h(),s=this.cachedLicense?.fingerprint??await y(this.getOrCreateDeviceFingerprint(),U());if(t!==this.generation)return false;let n=await this.saveCache({licenseKey:e,licenseId:`token:${i.accountHash}`,valid:true,isPro:false,tier:"free",expiresAt:null,cachedAt:r,lastValidatedAt:r,fingerprint:s,deviceName:this.cachedLicense?.deviceName??$(),quiet:true},t);return t!==this.generation||!n?false:(this.cachedLicense=n,this.applyTier("free"),this.state.isValidating=false,this.state.expiresAt=null,this.setVerifiedAt(r),this.retryAttempt=0,this.emit({type:"validated",isPro:false}),true)}standDown(e,t,i,r){if(t!==this.generation)return false;this.state.isValidating=false;let s=this.cachedLicense;return s&&s.licenseKey===e&&_(s)&&this.isCacheValid(s)?(this.applyTier(E(s)),this.state.error=null,this.state.errorKind=null,this.state.expiresAt=s.expiresAt?new Date(s.expiresAt):null,this.setVerifiedAt(s.cachedAt),this.keyTier()!=="pro"&&this.scheduleRetryIn(e,r),this.emit({type:"validated",isPro:this.state.isPro}),true):(this.state.error=i,this.state.errorKind="transport",this.scheduleRetryIn(e,r),this.emit({type:"error",isPro:this.state.isPro,error:i}),false)}scheduleRetryIn(e,t){this.cancelRetry();let i=this.generation;this.retryTimer=setTimeout(()=>{this.retryTimer=null,i===this.generation&&(this.state.isValidating||this.setLicenseKey(e,{force:true,isRetry:true}))},Math.max(1,Math.min(t,2147483647))),typeof p<"u"&&p&&(g.__LICENSE_MANAGER_RETRY_TIMER__=this.retryTimer)}cancelRetry(){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(),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,this.expiryTimer&&clearTimeout(this.expiryTimer),this.expiryTimer=null}getTier(){return this.credential().tier}credential(){let e=this.keyTier(),t=this.sessionTier();return t!==null&&(!this.hasKeyAccess()||t==="pro"&&e!=="pro")?{source:"session",tier:t}:{source:this.state.tierSource,tier:e}}keyTier(){return!this.hasKeyAccess()||this.state.expiresAt&&h()>=this.state.expiresAt.getTime()?"free":this.state.tier}sessionTier(){let e=v.getStatus();return e.state!=="active"?null:e.claims.tier==="free"?"free":"pro"}isPro(){return this.getTier()==="pro"}hasEntitlement(e){return this.isPro()}getState(){let{source:e,tier:t}=this.credential(),i=this.getTeamAccess();return{...this.state,tier:t,tierSource:e,isPro:t==="pro",access:this.getAccountAccess(),teamRole:i.role,allowedTools:i.tools}}getTeamAccess(){let e=v.getStatus();if(e.state==="active")return _e(e.claims);let t=this.devToken;return t&&t.token===this.state.licenseKey&&this.state.tierSource==="key"&&h()<t.claims.exp*1e3&&this.hasKeyAccess()?_e(t.claims):jt}getAccountAccess(){let e=this.getKeyAccess();if(e.status==="admitted")return e;let t=v.getStatus();return t.state==="active"?{status:"admitted",reason:null,validUntil:t.validUntil}:e}getKeyAccess(){return fe({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"}hasKeyAccess(){return this.getKeyAccess().status==="admitted"}setVerifiedAt(e){this.verifiedAt=e,this.expiryTimer&&clearTimeout(this.expiryTimer);let t=e+N,i=this.state.expiresAt?.getTime(),r=(i&&i>h()?Math.min(t,i):t)-h();this.expiryTimer=setTimeout(()=>{this.expiryTimer=null,this.verifiedAt===e&&(this.emit({type:"validated",isPro:this.isPro()}),h()<t&&this.setVerifiedAt(e))},Math.max(1,Math.min(r,2147483647))),typeof p<"u"&&p&&(g.__LICENSE_MANAGER_EXPIRY_TIMER__=this.expiryTimer)}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}onDeviceRegistrationNeeded(e){return this.deviceRegistrationCallback=e,()=>{this.deviceRegistrationCallback=null}}async completeDeviceRegistration(e){if(!this.pendingRegistration){console.warn("[Buoy] No pending device registration");return}let{licenseId:t,licenseKey:i,fingerprint:r}=this.pendingRegistration,s=this.generation,n=e.trim()||$(),c=ne();try{await ie(t,i,r,n,c)}catch(o){let a=o instanceof Error?o.message:String(o);if(!(a==="FINGERPRINT_TAKEN"||a==="MACHINE_LIMIT_EXCEEDED"))throw console.warn("[Buoy] Device registration failed:",a),o}if(s===this.generation){if(this.cachedLicense?.licenseKey===i){let o=await this.saveCache({...this.cachedLicense,fingerprint:r,deviceName:n},s);if(s!==this.generation)return;o&&(this.cachedLicense=o)}this.pendingRegistration=null}}emit(e){[...this.listeners].forEach(t=>{try{t(e)}catch(i){console.warn("[Buoy]","[React Buoy] License listener error:",i)}})}isCacheValid(e){let t=h()-e.cachedAt;return!(!e.valid||!Number.isFinite(e.cachedAt)||t<0||t>=N)}isCacheFresh(e){let t=this.isQuiet(e)?Oe:Ne;return h()-(e.lastValidatedAt??0)<t}isQuiet(e){return e.quiet!==void 0?e.quiet:E(e)==="free"&&!F()}async loadHold(){if(this.hold!==void 0)return this.hold;try{let e=await(await w()).getItem(D),t=e?JSON.parse(e):null;this.hold=t&&typeof t=="object"?t:null}catch{this.hold=null}return this.hold}async saveHold(e){this.hold=e;try{let t=await w();e?await t.setItem(D,JSON.stringify(e)):await t.removeItem(D)}catch{}}async persistCache(e){let t=ce(e);return await(await w()).setItem(M,JSON.stringify(t)),t}saveCache(e,t){let i=this.persistence.catch(()=>{}).then(async()=>{if(t!==this.generation)return null;let r=await this.persistCache(e);return t===this.generation?r:null});return this.persistence=i,y(i,ce(e))}async loadCachedLicense(){try{await this.persistence.catch(()=>{});let e=await(await w()).getItem(M);if(!e)return null;let t=JSON.parse(e);if(t.fingerprint){let i=await y(this.getOrCreateDeviceFingerprint(t.fingerprint).catch(()=>null),null);if(i&&this.fingerprintRestored&&t.fingerprint!==i)return{...t,fingerprint:void 0,deviceName:void 0}}return t}catch(e){return console.warn("[Buoy] Error loading cached license:",e),null}}getOrCreateDeviceFingerprint(e){return this.fingerprintPromise||(this.fingerprintPromise=(async()=>{let t=await w(),i=await t.getItem(V),r=await t.getItem(q),s=await y(Je().catch(()=>null),null),n=Ye({stored:i,storedOwner:r,marker:s?Xe(s):null,blobFingerprint:e??this.cachedLicense?.fingerprint,mint:U});return this.fingerprintRestored=n.restored,n.changed&&(await t.setItem(V,n.fingerprint),n.owner&&await t.setItem(q,n.owner)),n.fingerprint})()),this.fingerprintPromise}async clearCachedLicense(){this.cachedLicense=null;let e=this.persistence.catch(()=>{}).then(async()=>{await(await w()).removeItem(M)});this.persistence=e,await y(e.catch(()=>{}),void 0)}registerDeviceAsync(e,t,i,r){let s=ne();ie(e,t,i,r,s).catch(n=>{n.message!=="FINGERPRINT_TAKEN"&&n.message!=="MACHINE_LIMIT_EXCEEDED"&&console.warn("[Buoy] Device registration failed (non-blocking):",n.message)})}validateInBackground(e){this.setLicenseKey(e,{force:true,isRetry:true})}refreshAccess(){this.emit({type:"validated",isPro:this.isPro()})}startRevalidationTimer(){this.removeForegroundListener||(this.removeForegroundListener=gt(()=>this.refreshAccess()),typeof p<"u"&&p&&(g.__LICENSE_MANAGER_FOREGROUND_OFF__=this.removeForegroundListener)),this.revalidationTimer&&clearInterval(this.revalidationTimer),this.revalidationTimer=setInterval(()=>{if(!this.state.licenseKey||this.state.isValidating)return;let e=this.cachedLicense;e&&e.licenseKey===this.state.licenseKey&&this.isCacheFresh(e)||this.validateInBackground(this.state.licenseKey)},Re),typeof p<"u"&&p&&(globalThis.__LICENSE_MANAGER_TIMER__=this.revalidationTimer)}stopRevalidationTimer(){this.removeForegroundListener?.(),this.removeForegroundListener=null,this.expiryTimer&&clearTimeout(this.expiryTimer),this.expiryTimer=null,this.revalidationTimer&&(clearInterval(this.revalidationTimer),this.revalidationTimer=null),this.cancelRetry()}async forceReregister(){this.cachedLicense&&(this.cachedLicense.fingerprint=void 0,this.cachedLicense.deviceName=void 0),this.fingerprintPromise=null,await this.clearCachedLicense();try{await(await w()).removeItem(V)}catch{}}},Ht=new Bt,g=globalThis;typeof p<"u"&&p&&(g.__LICENSE_MANAGER_FOREGROUND_OFF__?.(),g.__LICENSE_MANAGER_FOREGROUND_OFF__=void 0,g.__LICENSE_MANAGER_EXPIRY_TIMER__&&clearTimeout(g.__LICENSE_MANAGER_EXPIRY_TIMER__),g.__LICENSE_MANAGER_TIMER__&&clearInterval(g.__LICENSE_MANAGER_TIMER__),g.__LICENSE_MANAGER_RETRY_TIMER__&&(clearTimeout(g.__LICENSE_MANAGER_RETRY_TIMER__),g.__LICENSE_MANAGER_RETRY_TIMER__=void 0));export{h as a,A as b,ee as c,ue as d,fe as e,d as f,v as g,z as h,b as i,Dt as j,Te as k,Ae as l,Ht as m};/*!
|
|
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
|
-
* PROPRIETARY — Buoy Pro license enforcement. NOT open source.
|
|
8
|
-
*
|
|
9
|
-
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
|
10
|
-
* (https://buoy.gg/terms), not an OSS license.
|
|
11
|
-
*
|
|
12
|
-
* This file configures the technological measure that controls access to paid
|
|
13
|
-
* Buoy Pro features. Modifying, patching, aliasing, stubbing, or otherwise
|
|
14
|
-
* altering it — including repointing `apiUrl` at a stand-in license server — so
|
|
15
|
-
* that Pro features unlock without a valid license is a breach of the EULA and,
|
|
16
|
-
* in the United States, circumvention of an access control under 17 U.S.C.
|
|
17
|
-
* § 1201, which applies whether or not any code is copied.
|
|
18
|
-
*
|
|
19
|
-
* Pro is $9/mo, and is free every weekend for anyone holding a key —
|
|
20
|
-
* including a free one (`npx --package=@buoy-gg/core buoy login`). Buy a key at
|
|
21
|
-
* https://buoy.gg or use it free on Saturday and Sunday.
|
|
22
|
-
*//*!
|
|
23
|
-
* PROPRIETARY — Buoy Pro license enforcement. NOT open source.
|
|
24
|
-
*
|
|
25
|
-
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
|
26
|
-
* (https://buoy.gg/terms), not an OSS license.
|
|
27
|
-
*
|
|
28
|
-
* This file is part of the technological measure that controls access to paid
|
|
29
|
-
* Buoy Pro features. Modifying, patching, aliasing, stubbing, or otherwise
|
|
30
|
-
* altering it so that Pro features unlock without a valid license is a breach
|
|
31
|
-
* of the EULA and, in the United States, circumvention of an access control
|
|
32
|
-
* under 17 U.S.C. § 1201 — which applies whether or not any code is copied.
|
|
33
|
-
*
|
|
34
|
-
* Pro is $9/mo, and is free every weekend for anyone holding a key —
|
|
35
|
-
* including a free one (`npx --package=@buoy-gg/core buoy login`). Buy a key at
|
|
36
|
-
* https://buoy.gg or use it free on Saturday and Sunday.
|
|
37
|
-
*//*!
|
|
38
|
-
* PROPRIETARY — Buoy Pro license enforcement. NOT open source.
|
|
39
|
-
*
|
|
40
|
-
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
|
41
|
-
* (https://buoy.gg/terms), not an OSS license.
|
|
42
|
-
*
|
|
43
|
-
* This file is part of the technological measure that controls access to paid
|
|
44
|
-
* Buoy Pro features: it decides which tier a validated key grants. Modifying,
|
|
45
|
-
* patching, aliasing, stubbing, or otherwise altering it so that Pro features
|
|
46
|
-
* unlock without a valid license is a breach of the EULA and, in the United
|
|
47
|
-
* States, circumvention of an access control under 17 U.S.C. § 1201 — which
|
|
48
|
-
* applies whether or not any code is copied.
|
|
49
|
-
*
|
|
50
|
-
* Pro is $9/mo, and is free every weekend for anyone holding a key —
|
|
51
|
-
* including a free one (`npx --package=@buoy-gg/core buoy login`). Buy a key at
|
|
52
|
-
* https://buoy.gg or use it free on Saturday and Sunday.
|
|
53
|
-
*//*!
|
|
54
|
-
* PROPRIETARY — Buoy license enforcement. NOT open source.
|
|
55
|
-
*
|
|
56
|
-
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
|
57
|
-
* (https://buoy.gg/terms), not an OSS license.
|
|
58
|
-
*//*!
|
|
59
|
-
* PROPRIETARY — Buoy Pro license enforcement. NOT open source.
|
|
60
|
-
*
|
|
61
|
-
* Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
|
|
62
|
-
* (https://buoy.gg/terms), not an OSS license.
|
|
63
|
-
*
|
|
64
|
-
* This file is the technological measure that controls access to paid Buoy Pro
|
|
65
|
-
* features. Modifying, patching, aliasing, stubbing, or otherwise altering it
|
|
66
|
-
* so that Pro features unlock without a valid license is a breach of the EULA
|
|
67
|
-
* and, in the United States, circumvention of an access control under
|
|
68
|
-
* 17 U.S.C. § 1201 — which applies whether or not any code is copied.
|
|
69
|
-
*
|
|
70
|
-
* Pro is $9/mo, and is free every weekend for anyone holding a key —
|
|
71
|
-
* including a free one (`npx --package=@buoy-gg/core buoy login`). Buy a key at
|
|
72
|
-
* https://buoy.gg or use it free on Saturday and Sunday.
|
|
73
|
-
*/
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use client";import{b as R}from"./chunk-J7MW3NXU.mjs";var $="__BUOY_CAPACITOR_BRIDGE__",x=300;function w(){let e=globalThis.Capacitor;return e&&typeof e=="object"?e:null}function g(){let e=globalThis,t=e[$];return(!t||t.version!==1)&&(t={version:1,originalPromise:null,originalCallback:null,wrappedPromise:null,wrappedCallback:null,interceptors:[],listeners:new Map,log:[],subscribers:new Set,seq:0,fakeIds:0},e[$]=t),t}function k(){let e=globalThis.__buoyRealNow;return typeof e=="function"?e():Date.now()}function G(e){e.clickListenerInstalled||typeof window>"u"||typeof window.addEventListener!="function"||(e.clickListenerInstalled=true,window.addEventListener("click",t=>{let r=t.composedPath?.()[0]??t.target;for(e.buoyClick=false;r;){if(r.closest?.("[data-buoy-root], [data-buoy-portal-host]")){e.buoyClick=true;break}r=r.getRootNode?.().host??null}e.clickTimer&&clearTimeout(e.clickTimer),e.clickTimer=setTimeout(()=>{e.buoyClick=false},0)},true))}function C(e){return e&&typeof e=="object"?e:{}}function W(e,t,r,n){if(t!=="SentryCapacitor"||r!=="addBreadcrumb")return false;let o=C(n);if(o.category==="ui.click")return e.buoyClick===true;if(o.category==="console"&&typeof o.message=="string")return/^\[(?:buoy(?:[^\]]*)?|@buoy-gg\/[^\]]+|RnBetterDevTools|React ?Buoy|RN-BUOY DEBUG|js-top|perf-monitor|impersonate|RenderCause|HighlightUpdates|RenderTracker|ProfilerInterceptor|HighlightPerf|DebugBorders|optional-module|route-events|RouteObserver)\]/i.test(o.message);if(o.category!=="fetch"&&o.category!=="xhr")return false;let i=C(o.data);if(typeof i.url!="string")return false;try{let a=new URL(i.url,typeof location>"u"?"http://localhost":location.href),f=a.hostname.toLowerCase();if(["api.buoy.gg","ai.buoy.gg","gateway.buoy.gg"].includes(f)||f==="keygen.sh"||f.endsWith(".keygen.sh")||["buoy.gg","www.buoy.gg"].includes(f)&&/^\/api\/(license|settings|auth|session|install|t)(?:\/|$)/.test(a.pathname)||a.pathname==="/buoy-assets.json")return true;let l=globalThis.__BUOY_INTERNAL_HOSTS__;return l instanceof Set&&[...l].some(s=>typeof s=="string"&&s.toLowerCase()===a.host.toLowerCase())}catch{return false}}function P(e){for(let t of Array.from(e.subscribers))try{t()}catch{}}function S(e,t){let r={seq:++e.seq,...t};return e.log.push(r),e.log.length>x&&e.log.splice(0,e.log.length-x),P(e),r}function D(e,t,r){return e.interceptors.filter(n=>(n.plugin==="*"||n.plugin===t.plugin)&&(!n.methods||n.methods.includes(t.method))&&typeof n[r]=="function").map((n,o)=>({interceptor:n,index:o})).sort((n,o)=>(o.interceptor.order??0)-(n.interceptor.order??0)||n.index-o.index).map(n=>n.interceptor)}function T(e,t){return`${e}:${String(t)}`}function V(){return`buoy-${++g().fakeIds}`}function Q(e={}){if(!R())return false;let t=w();if(!t||typeof t.nativePromise!="function"||typeof t.nativeCallback!="function")return false;let r=g();if(r.wrappedPromise&&t.nativePromise===r.wrappedPromise&&t.nativeCallback===r.wrappedCallback)return true;if(t.DEBUG!==true&&e.release!==true)return false;r.originalPromise=t.nativePromise,r.originalCallback=t.nativeCallback;let n=r.originalPromise,o=r.originalCallback,i=(l,s,h,v)=>{let p={plugin:l,method:s,options:C(h)},m=D(r,p,"promise"),u=d=>{if(d>=m.length){if(v(),s==="removeAllListeners")for(let y of Array.from(r.listeners.keys()))y.startsWith(`${l}:`)&&r.listeners.delete(y);return n.call(t,l,s,h)}try{return Promise.resolve(m[d].promise(p,()=>u(d+1)))}catch(y){return Promise.reject(y)}};return u(0)};r.runPromise=i;let a=(l,s,h)=>{if(W(r,l,s,h))return i(l,s,h,()=>{});let v=S(r,{plugin:l,method:s,kind:"promise",options:C(h),start:k()}),p=false,m=i(l,s,h,()=>{p=true});return m.then(u=>{Object.assign(v,{end:k(),ok:true,result:u,answeredByBuoy:!p}),P(r)},u=>{Object.assign(v,{end:k(),ok:false,error:u,answeredByBuoy:!p}),P(r)}),m},f=(l,s,h,v)=>{let p=h,m=v;typeof p=="function"&&(m=p,p=null);let u={plugin:l,method:s,options:C(p)},d=S(r,{plugin:l,method:s,kind:"callback",options:u.options,start:k(),events:0}),y=false,A=D(r,u,"callback"),j=(b,c)=>b>=A.length?(y=true,o.call(t,l,s,p,c)):A[b].callback(u,c,_=>j(b+1,_)),U=s==="addListener",O=j(0,(b,c)=>{if(d.events=(d.events??0)+1,!U&&d.end===void 0)d.end=k(),d.ok=!c,c?d.error=c:d.result=b,P(r);else{let _=k();S(r,{plugin:l,method:U?String(u.options.eventName??"event"):s,kind:"event",options:{},start:_,end:_,ok:!c,...c?{error:c}:{result:b}})}m?.(b,c)});if(d.answeredByBuoy=!y,s==="addListener"&&O!=null&&typeof m=="function"){let b=T(l,u.options.eventName),c=r.listeners.get(b);c||r.listeners.set(b,c=new Map),c.set(String(O),m)}else s==="removeListener"&&r.listeners.get(T(l,u.options.eventName))?.delete(String(u.options.callbackId));return O};return t.nativePromise=a,t.nativeCallback=f,r.wrappedPromise=a,r.wrappedCallback=f,G(r),J(),true}var z=/^\s*\(\s*prefers-color-scheme\s*:\s*(dark|light)\s*\)\s*$/i,I="__BUOY_COLOR_SCHEME_QUERIES__";function H(e){let t=z.exec(e);return t?t[1].toLowerCase():null}function J(){let e=globalThis,t=globalThis.WeakRef;if(e[I]||typeof e.matchMedia!="function"||!t)return;let r=[];e[I]=r;let n=e.matchMedia;e.matchMedia=function(o){let i=n.call(this??globalThis,o);if(i&&H(String(o))){for(let a=r.length-1;a>=0;a--)r[a].deref()||r.splice(a,1);r.push(new t(i))}return i}}function K(){let e=globalThis[I];return e?e.map(t=>t.deref()).filter(t=>!!t):[]}function M(){let e=w(),t=g();return!!(t.wrappedPromise&&e?.nativePromise===t.wrappedPromise)}function X(e){let t=g();return t.interceptors.push(e),()=>{let r=t.interceptors.indexOf(e);r>=0&&t.interceptors.splice(r,1)}}function Z(e,t,r){let n=g().listeners.get(T(e,t));if(!n)return 0;let o=0;for(let i of Array.from(n.values()))try{i(r),o++}catch(a){globalThis.console?.error(a)}return o}function F(e,t){return g().listeners.get(T(e,t))?.size??0}function Y(e){return w()?.PluginHeaders?.find(t=>t.name===e)}function N(e){if(!R())return false;try{return!!Y(e)||w()?.isPluginAvailable?.(e)===true}catch{return false}}function E(){let e=w(),t=g();return{cap:e,promise:t.originalPromise??e?.nativePromise??null,callback:t.originalCallback??e?.nativeCallback??null}}function L(e,t,r={}){let{cap:n,promise:o}=E();return!n||!o?Promise.reject(new Error("Capacitor bridge unavailable")):o.call(n,e,t,r)}function ee(e,t,r={}){let n=g().runPromise;return n&&M()?n(e,t,r,()=>{}):L(e,t,r)}function te(e,t,r,n){let{cap:o,callback:i}=E();return!o||!i?null:i.call(o,e,t,r,n)}function q(e,t,r){let{cap:n,promise:o,callback:i}=E();if(!n||!i)return Promise.reject(new Error("Capacitor bridge unavailable"));let a=i.call(n,e,"addListener",{eventName:t},l=>r(l)),f=async()=>{if(a==null)return;let l={eventName:t,callbackId:a};Y(e)?.methods?.find(s=>s.name==="removeListener")?.rtype==="promise"&&o?await o.call(n,e,"removeListener",l):i.call(n,e,"removeListener",l,()=>{})};return Promise.resolve({remove:f})}function re(){return g().log}function ne(){let e=g();e.log.length=0,P(e)}function oe(e){let t=g();return t.subscribers.add(e),()=>{t.subscribers.delete(e)}}var ie=new Set(["then","catch","finally","$$typeof","toJSON","constructor"]);function le(e){return N(e)?new Proxy({},{get(t,r){if(!(typeof r!="string"||ie.has(r)))return r==="addListener"?(n,o)=>q(e,n,o):n=>L(e,r,n??{})}}):null}var B="__BUOY_CAPACITOR_HOST__";function ae(){if(!R())return Promise.resolve(null);let e=globalThis,t=e[B];if(t)return t;let r=i=>typeof i=="string"&&i?i:null,n=async i=>{if(!N(i))return{};try{return await L(i,"getInfo")??{}}catch{return{}}},o=Promise.all([n("App"),n("Device")]).then(([i,a])=>{let f={isSimulator:typeof a.isVirtual=="boolean"?a.isVirtual:null,deviceName:r(a.name),bundleId:r(i.id),appName:r(i.name)};return e[`${B}_value`]=f,f});return e[B]=o,o}function se(){return globalThis[`${B}_value`]??null}export{V as a,Q as b,H as c,K as d,M as e,X as f,Z as g,F as h,N as i,L as j,ee as k,te as l,q as m,re as n,ne as o,oe as p,le as q,ae as r,se as s};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use client";var l=(()=>{try{let t=globalThis.Capacitor;if(t&&typeof t.isNativePlatform=="function"&&t.isNativePlatform())return t.DEBUG===true}catch{}return process.env.NODE_ENV!=="production"})();typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis);function r(){let t=globalThis.Capacitor;return t&&typeof t=="object"?t:null}function o(){try{return r()?.isNativePlatform?.()===true}catch{return false}}function a(){if(!o())return null;try{let t=r()?.getPlatform?.();return t==="ios"||t==="android"?t:null}catch{return null}}function n(){return o()?r()?.DEBUG===true:null}function e(t){return n()??t}export{l as a,o as b,a as c,n as d,e};
|