@jchat/runtime 1.0.0-alpha.26 → 1.0.0-alpha.27
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/CHANGELOG.md +11 -0
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @jchat/runtime
|
|
2
2
|
|
|
3
|
+
## 1.0.0-alpha.27
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Update registry activation and check client to parse standardized response envelope
|
|
8
|
+
|
|
9
|
+
- Standardize Bun.env usage and eliminate redundant process.env dual checks
|
|
10
|
+
|
|
11
|
+
- Bumped `@jchat/*` dependencies:
|
|
12
|
+
- [`shared@1.0.0-alpha.25`](https://github.com/jchatcloud/jchat/releases/tag/shared@v1.0.0-alpha.25)
|
|
13
|
+
|
|
3
14
|
## 1.0.0-alpha.26
|
|
4
15
|
|
|
5
16
|
No changes in this release.
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"node:crypto";import t from"node:net";import n from"node:fs/promises";import r from"node:path";import i from"node:fs";import{Elysia as a}from"elysia";const o=`https://license.jchatcloud.com`,s=`https://license.jchatcloud.com`,c=`jchat-chat`,l=new Set([`localhost`,`127.0.0.1`,`::1`]),u=[`.local`,`.test`,`.invalid`,`.example`];function d(e){let t=e.trim();if(!t)throw Error(`Instance domain is required`);let n=new URL(t.includes(`://`)?t:`https://${t}`).hostname.toLowerCase().replace(/\.$/,``),r=n===`www.localhost`?`localhost`:n.replace(/^www\./,``);if(!r||r.includes(`@`)||/\s/.test(r))throw Error(`Invalid instance domain`);return{host:r,isLocalhost:l.has(r)}}function f(e){let{host:n,isLocalhost:r}=d(e);return!r&&t.isIP(n)===0&&n.includes(`.`)&&!u.some(e=>n.endsWith(e))}function p(e){try{return d(e).isLocalhost||f(e)}catch{return!1}}function m(e){try{return d(e).isLocalhost}catch{return!1}}function h(e){let{host:n,isLocalhost:r}=d(e);if(r||t.isIP(n)!==0)return null;let i=n.split(`.`);if(i.length<=2)return n;let a=new Set([`co`,`com`,`org`,`net`,`gov`,`edu`,`ac`,`sch`]),o=i.at(-1)??``,s=i.at(-2)??``;return a.has(s)&&o.length===2&&i.length>=3?i.slice(-3).join(`.`):i.slice(-2).join(`.`)}function g(e,t){try{let n=d(e).host,r=d(t).host;if(n===r||n.endsWith(`.${r}`))return!0;let i=h(n),a=h(r);return!!(i&&a&&i===a)}catch{return!1}}function _(e,t,n,r=`current-host`){let i=d(e).host;return n===`subdomain`&&t&&r===`parent-domain`?h(i)??i:i}function v(e={}){let t=r.resolve(e.cwd??process.cwd()),n=e.env??Bun.env,i=b(t);return{repoRoot:i,runtimeRoot:t,uploadsDir:x(n.JCHAT_UPLOADS_DIR,t,i,`uploads`,`uploads`),addonBundlesDir:x(n.JCHAT_ADDONS_DIR,t,i,`addons`,`addons`),addonSourceDir:i?r.join(i,`addons`):r.join(t,`addons`),migrationsDir:x(n.JCHAT_MIGRATIONS_DIR,t,i,r.join(`packages`,`db`,`migrations`),`migrations`),dataDir:x(n.JCHAT_DATA_DIR,t,i,`data`,`data`)}}function y(e){return i.existsSync(r.join(e,`package.json`))&&i.existsSync(r.join(e,`apps`))&&i.existsSync(r.join(e,`packages`))}function b(e){let t=r.resolve(e);for(;;){if(y(t))return t;let e=r.dirname(t);if(e===t)return null;t=e}}function x(e,t,n,i,a){return e?r.resolve(e):n?r.join(n,i):r.join(t,a)}function S(){return v().dataDir}const C=r.join(S(),`instance.json`);function w(){return{installationId:Bun.randomUUIDv7()}}function T(e=C){try{if(!i.existsSync(e))return``;let t=i.readFileSync(e,`utf8`);return JSON.parse(t)?.instanceToken??``}catch{return``}}async function E(e=C){try{let t=Bun.file(e);if(!await t.exists())return null;let n=JSON.parse(await t.text());if(!n||typeof n!=`object`)return null;let r=n;return r.version!==1||typeof r.installationId!=`string`||!r.installationId||typeof r.instanceToken!=`string`||!r.instanceToken?null:r}catch{return null}}async function D(e,t=C){let i=r.dirname(t);await n.mkdir(i,{recursive:!0});let a=`${t}.${process.pid}.${Bun.randomUUIDv7()}.tmp`;await Bun.write(a,`${JSON.stringify(e,null,2)}\n`),await n.rename(a,t)}async function ee(e,t=C){let n=await E(t);if(!n)throw Error(`Local license state is missing`);await D({...n,instanceToken:e,lastSuccessfulCheckAt:new Date().toISOString()},t)}function O(e){if(e)return e.length<=8?`redacted`:`${e.slice(0,4)}…${e.slice(-4)}`}async function te(e,t,i=r.join(S(),`license-events.log`)){await n.mkdir(r.dirname(i),{recursive:!0});let a=JSON.stringify({at:new Date().toISOString(),event:e,domain:O(t.domain),installationId:O(t.installationId),reference:O(t.reference)});await n.appendFile(i,`${a}\n`,`utf8`)}let k=`unavailable`,A=`startup`,j;function ne(e){j=e}function M(t,n=e.randomUUID()){k=t,A=n,t===`invalid`&&j?.()}function N(){return{status:k,reference:A}}function P(){return k===`invalid`}function F(e=Bun.env.NODE_ENV===`production`){return!!(k===`invalid`||e&&k===`unavailable`)}function I(){return Bun.env.JCHAT_LICENSE_SERVER_URL||(Bun.env.NODE_ENV===`development`||Bun.env.NODE_ENV===`test`?`http://localhost:4100`:o)}async function L(e){try{let t=e.registryEndpoint??I(),n=await(e.fetchImpl??fetch)(`${t}/api/v1/activate`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({purchaseCode:e.purchaseCode,domain:d(e.domain).host,siteSlug:e.siteSlug,domainScope:e.domainScope,provider:e.provider,routingMode:e.routingMode,installationId:e.installationId,environment:d(e.domain).isLocalhost?`development`:`production`})}),r=await n.json();return n.ok===!1||!r.success||!r.token?{success:!1,message:r.message??`This license is already active on another domain. Please deactivate it first.`}:{success:!0,buyer:r.buyer??`Customer`,token:r.token,domain:r.domain??d(e.domain).host}}catch{return{success:!1,message:`Failed to connect to the central registry. Please try again later.`}}}async function R(e,t,n,r,i,a=`envato`,o=fetch){let s=w();try{let c=await L({purchaseCode:e,domain:t,siteSlug:n,domainScope:r,routingMode:i,provider:a,installationId:s.installationId,fetchImpl:o});return c.success?{valid:!0,buyer:c.buyer,token:c.token,domain:c.domain,state:s}:{valid:!1,error:c.message}}catch{return{valid:!1,error:`Failed to verify license. Check your internet connection.`}}}const z=new Set([`/health`,`/api/v1/license/status`]);async function B(e={}){if(!(e.isPrimaryWorker??(!Bun.env.WORKER_ID||Bun.env.WORKER_ID===`0`)))return;let t=e.domain??`localhost`;if(e.onInvalidate&&ne(e.onInvalidate),m(t)){M(`valid`);return}let n=await E();if(!n?.instanceToken){M(e.isBootstrapComplete?`valid`:`unavailable`);return}if(e.signingKey&&!Z(n.instanceToken,t,{publicKeyPem:e.signingKey})){M(`invalid`,`domain-mismatch`);return}if(await W(e)>(m(t)?1/0:$(n.instanceToken))){M(`invalid`,`multi-site-unauthorized`);return}M(`valid`)}function V(e={}){B(e);let t=e.allowedPaths??z;return new a({name:`jchatRuntime`}).derive({as:`global`},()=>({runtimeStatus:N()})).onBeforeHandle({as:`global`},async({request:n,set:r})=>{if(n.method===`POST`&&n.url.includes(`/owner/sites`)){let t=e.domain??`localhost`,n=await E(),i=m(t)?1/0:$(n?.instanceToken);if(await W(e)>=i)return r.status=403,{status:`license_restricted`,message:`Site creation limit reached (${i} site${i===1?``:`s`} allowed on your license). Please upgrade your license to create additional sites.`,reference:`multi-site-unauthorized`}}return U(n,r,t)})}function H(e,t,n){return n.has(e)?!0:t===`invalid`?e===`/install/upgrade-license`:t===`unavailable`?e===`/install`||e.startsWith(`/install/`)||e.startsWith(`/assets/`)||e.startsWith(`/_`)||e===`/favicon.ico`:!1}function U(e,t,n=z,r=Bun.env.NODE_ENV===`production`){let{status:i,reference:a}=N(),o=e.headers.get(`host`)?.split(`:`)[0]?.toLowerCase();if(o&&f(o)&&m(Bun.env.JCHAT_DOMAIN||`localhost`))return t.status=403,{status:`license_invalid`,message:`Public domain deployment requires a valid license matching this domain.`,reference:`public-host-requires-license`};if(i!==`valid`&&i!==`unreachable-fallback`&&(r||i!==`unavailable`)&&!H(new URL(e.url).pathname.replace(/\/+$/,``)||`/`,i,n))return t.status=503,i===`unavailable`?{status:`license_unavailable`,message:`This JChat installation is not activated. Please complete the installation.`,reference:a}:{status:`license_invalid`,message:`This JChat installation is disabled because its license is invalid.`,reference:a}}async function W(e){let t=Bun.env.DATABASE_URL??process.env.DATABASE_URL;if(t&&typeof Bun<`u`&&`SQL`in Bun)try{let e=new Bun.SQL(t),n=await e`SELECT count(*)::int as count FROM sites WHERE deleted_at IS NULL`;if(await e.close(),n?.[0]?.count!==void 0&&n[0].count!==null)return Number(n[0].count)}catch{}if(e.getSiteCount)try{return await e.getSiteCount()}catch{return 0}return 0}function G(t,n=`production`,r){let i={...t},a=!0;typeof i.JCHAT_COOKIE_SECRET!=`string`&&(i.JCHAT_COOKIE_SECRET=``);try{let t=T();if(n===`developer-sandbox`)a=!0;else if(!t)a=!1,n===`production`&&(i.JCHAT_COOKIE_SECRET=e.randomBytes(64).toString(`hex`));else{let o=typeof i.JCHAT_DOMAIN==`string`?i.JCHAT_DOMAIN:void 0,s=typeof i.NODE_ENV==`string`?i.NODE_ENV:void 0;if(!o||!p(o)||s===`production`&&!f(o))throw Error(`A valid installed JChat public domain is required for production deployments.`);if(!Z(t,o||`localhost`,{publicKeyPem:r}))a=!1,n===`production`&&(i.JCHAT_COOKIE_SECRET=e.randomBytes(64).toString(`hex`));else{let r=X(t);if(s===`production`&&r?.environment===`development`)a=!1,n===`production`&&(i.JCHAT_COOKIE_SECRET=e.randomBytes(64).toString(`hex`));else{let n=t.split(`.`),a=n[2]||``;if(a&&r){let t=e.createHmac(`sha256`,a).update(`${n[0]}.${n[1]}:${r.domain}:${r.installationId}`).digest(`hex`);i.JCHAT_COOKIE_SECRET+=t}}}}}catch{a=!1,n===`production`&&(i.JCHAT_COOKIE_SECRET=e.randomBytes(64).toString(`hex`))}return i.SYSTEM_BOOTSTRAP_COMPLETE=a,i}function re(e,t=`production`,n){return G(e,t,n)}function K(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function q(e){return typeof e==`string`&&e.trim().length>0}function J(e){if(!e)return null;try{return JSON.parse(Buffer.from(e,`base64url`).toString(`utf8`))}catch{return null}}function Y(e){let t=e.split(`.`);if(t.length!==3)return null;let n=J(t[0]);return!K(n)||n.alg!==`RS256`||n.typ!==`JWT`?null:{alg:`RS256`,typ:`JWT`}}function ie(e){if(!K(e))return null;let{iss:t,aud:n,licenseId:r,domain:i,buyer:a,installationId:o,plan:s,entitlements:c,purchaseProvider:l,environment:u,routingMode:p,iat:m,exp:h,isTrial:g,stages:_,channel:v,limits:y}=e;if(!q(t)||!q(n)||!q(r)||!q(i)||!q(a)||!q(o)||!q(s)||!Array.isArray(c)||!c.every(q)||l!==`envato`&&l!==`jchat`||u!==`production`&&u!==`development`||p!==`path`&&p!==`subdomain`||typeof m!=`number`||!Number.isSafeInteger(m)||m<0||h!==void 0&&(typeof h!=`number`||!Number.isSafeInteger(h)||h<0)||g!==void 0&&typeof g!=`boolean`)return null;let b=new Set([`stable`,`beta`,`experimental`]),x;if(_!==void 0){if(!Array.isArray(_)||!_.every(e=>typeof e==`string`&&b.has(e)))return null;x=_}let S=new Set([`stable`,`lts`]),C;if(v!==void 0){if(typeof v!=`string`||!S.has(v))return null;C=v}let w;if(y!==void 0){if(!K(y)||typeof y.maxSites!=`number`||!Number.isSafeInteger(y.maxSites))return null;w={maxSites:y.maxSites,...typeof y.maxRoomsPerSite==`number`&&Number.isSafeInteger(y.maxRoomsPerSite)?{maxRoomsPerSite:y.maxRoomsPerSite}:{}}}let T;try{T=d(i)}catch{return null}return u===`development`&&!T.isLocalhost||u===`production`&&!f(i)?null:{iss:t,aud:n,licenseId:r,domain:i,buyer:a,installationId:o,plan:s,entitlements:c,purchaseProvider:l,environment:u,routingMode:p,iat:m,...h===void 0?{}:{exp:h},...g===void 0?{}:{isTrial:g},...x===void 0?{}:{stages:x},...C===void 0?{}:{channel:C},...w===void 0?{}:{limits:w}}}function X(e){let t=e.split(`.`);return t.length!==3||!t.every(Boolean)||!Y(e)?null:ie(J(t[1]))}function Z(t,n,r){if(!t||t===`YOUR_LICENSE_KEY_PLACEHOLDER`)return!1;try{let i=t.split(`.`);if(i.length!==3||!Y(t))return!1;let a=X(t);if(!a)return!1;let o=r.issuer??Bun.env.JCHAT_LICENSE_ISSUER??`https://license.jchatcloud.com`,s=r.audience??Bun.env.JCHAT_LICENSE_AUDIENCE??`jchat-chat`;if(a.iss!==o||a.aud!==s)return!1;let c=d(n).host,l=d(a.domain).host;if(c!==l&&(a.routingMode!==`subdomain`||!c.endsWith(`.${l}`)))return!1;let u=Buffer.from(`${i[0]}.${i[1]}`),f=Buffer.from(i[2].replace(/-/g,`+`).replace(/_/g,`/`),`base64`);return e.verify(`sha256`,u,r.publicKeyPem,f)}catch{return!1}}function ae(e,t,n,r){if(r&&!Z(e,t,r))return!1;let i=X(e);return i?i.installationId===n:!1}function oe(e,t,n,r){return Z(e,t,r)?X(e)?.entitlements?.includes(n)??!1:!1}function se(e,t=`localhost`,n){if(n&&(!e||!Z(e,t,n))||!e)return!1;let r=X(e);return r?r.environment===`development`&&m(t)?!0:$(e)>1||(r.entitlements?.includes(`site.create.multi`)??!1):!1}function Q(e,t){return e?X(e)?.entitlements?.includes(t)??!1:!1}function ce(e,t){return t===`stable`?!0:e?(X(e)?.stages??[`stable`]).includes(t):!1}function $(e){return e?X(e)?.limits?.maxSites??1:1}function le(e){return e?X(e)?.channel??`stable`:`stable`}function ue(e){return $(e)>1||Q(e,`site.create.multi`)}export{c as DEFAULT_LICENSE_AUDIENCE,s as DEFAULT_LICENSE_ISSUER,o as DEFAULT_LICENSE_SERVER_URL,C as DEFAULT_STATE_PATH,L as activateRegistry,ue as canCreateMultiSite,w as createIdentity,b as findRepoRoot,$ as getMaxSites,le as getReleaseChannel,h as getRootDomain,N as getRuntimeStatus,Q as hasCapability,oe as hasEntitlement,ce as hasStageAccess,R as installAndActivate,p as isAllowedConfiguredDomain,P as isApplicationDisabled,m as isLocalhostDomain,g as isMatchingDomain,se as isMultiSiteAllowed,f as isPublicDomain,F as isRuntimeBlocked,V as jchatRuntime,re as loadServerContext,d as normalizeDomain,X as parsePayload,E as readState,T as readTokenSync,te as recordAudit,_ as resolveActivationDomain,S as resolveDataDir,v as resolveRuntimePaths,G as sealServerContext,M as setRuntimeStatus,B as startRuntimeSupervisor,ee as updateInstanceToken,ae as verifyEntitlement,Z as verifySignature,D as writeState};
|
|
1
|
+
import e from"node:crypto";import t from"node:net";import n from"node:fs/promises";import r from"node:path";import i from"node:fs";import{Elysia as a}from"elysia";const o=`https://license.jchatcloud.com`,s=`https://license.jchatcloud.com`,c=`jchat-chat`,l=new Set([`localhost`,`127.0.0.1`,`::1`]),u=[`.local`,`.test`,`.invalid`,`.example`];function d(e){let t=e.trim();if(!t)throw Error(`Instance domain is required`);let n=new URL(t.includes(`://`)?t:`https://${t}`).hostname.toLowerCase().replace(/\.$/,``),r=n===`www.localhost`?`localhost`:n.replace(/^www\./,``);if(!r||r.includes(`@`)||/\s/.test(r))throw Error(`Invalid instance domain`);return{host:r,isLocalhost:l.has(r)}}function f(e){let{host:n,isLocalhost:r}=d(e);return!r&&t.isIP(n)===0&&n.includes(`.`)&&!u.some(e=>n.endsWith(e))}function p(e){try{return d(e).isLocalhost||f(e)}catch{return!1}}function m(e){try{return d(e).isLocalhost}catch{return!1}}function h(e){let{host:n,isLocalhost:r}=d(e);if(r||t.isIP(n)!==0)return null;let i=n.split(`.`);if(i.length<=2)return n;let a=new Set([`co`,`com`,`org`,`net`,`gov`,`edu`,`ac`,`sch`]),o=i.at(-1)??``,s=i.at(-2)??``;return a.has(s)&&o.length===2&&i.length>=3?i.slice(-3).join(`.`):i.slice(-2).join(`.`)}function g(e,t){try{let n=d(e).host,r=d(t).host;if(n===r||n.endsWith(`.${r}`))return!0;let i=h(n),a=h(r);return!!(i&&a&&i===a)}catch{return!1}}function _(e,t,n,r=`current-host`){let i=d(e).host;return n===`subdomain`&&t&&r===`parent-domain`?h(i)??i:i}function v(e={}){let t=r.resolve(e.cwd??process.cwd()),n=e.env??Bun.env,i=b(t);return{repoRoot:i,runtimeRoot:t,uploadsDir:x(n.JCHAT_UPLOADS_DIR,t,i,`uploads`,`uploads`),addonBundlesDir:x(n.JCHAT_ADDONS_DIR,t,i,`addons`,`addons`),addonSourceDir:i?r.join(i,`addons`):r.join(t,`addons`),migrationsDir:x(n.JCHAT_MIGRATIONS_DIR,t,i,r.join(`packages`,`db`,`migrations`),`migrations`),dataDir:x(n.JCHAT_DATA_DIR,t,i,`data`,`data`)}}function y(e){return i.existsSync(r.join(e,`package.json`))&&i.existsSync(r.join(e,`apps`))&&i.existsSync(r.join(e,`packages`))}function b(e){let t=r.resolve(e);for(;;){if(y(t))return t;let e=r.dirname(t);if(e===t)return null;t=e}}function x(e,t,n,i,a){return e?r.resolve(e):n?r.join(n,i):r.join(t,a)}function S(){return v().dataDir}const C=r.join(S(),`instance.json`);function w(){return{installationId:Bun.randomUUIDv7()}}function T(e=C){try{if(!i.existsSync(e))return``;let t=i.readFileSync(e,`utf8`);return JSON.parse(t)?.instanceToken??``}catch{return``}}async function E(e=C){try{let t=Bun.file(e);if(!await t.exists())return null;let n=JSON.parse(await t.text());if(!n||typeof n!=`object`)return null;let r=n;return r.version!==1||typeof r.installationId!=`string`||!r.installationId||typeof r.instanceToken!=`string`||!r.instanceToken?null:r}catch{return null}}async function D(e,t=C){let i=r.dirname(t);await n.mkdir(i,{recursive:!0});let a=`${t}.${process.pid}.${Bun.randomUUIDv7()}.tmp`;await Bun.write(a,`${JSON.stringify(e,null,2)}\n`),await n.rename(a,t)}async function ee(e,t=C){let n=await E(t);if(!n)throw Error(`Local license state is missing`);await D({...n,instanceToken:e,lastSuccessfulCheckAt:new Date().toISOString()},t)}function O(e){if(e)return e.length<=8?`redacted`:`${e.slice(0,4)}…${e.slice(-4)}`}async function te(e,t,i=r.join(S(),`license-events.log`)){await n.mkdir(r.dirname(i),{recursive:!0});let a=JSON.stringify({at:new Date().toISOString(),event:e,domain:O(t.domain),installationId:O(t.installationId),reference:O(t.reference)});await n.appendFile(i,`${a}\n`,`utf8`)}let k=`unavailable`,A=`startup`,j;function ne(e){j=e}function M(t,n=e.randomUUID()){k=t,A=n,t===`invalid`&&j?.()}function N(){return{status:k,reference:A}}function P(){return k===`invalid`}function F(e=Bun.env.NODE_ENV===`production`){return!!(k===`invalid`||e&&k===`unavailable`)}function I(){return Bun.env.JCHAT_LICENSE_SERVER_URL||(Bun.env.NODE_ENV===`development`||Bun.env.NODE_ENV===`test`?`http://localhost:4100`:o)}async function L(e){try{let t=e.registryEndpoint??I(),n=await(e.fetchImpl??fetch)(`${t}/api/v1/activate`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({purchaseCode:e.purchaseCode,domain:d(e.domain).host,siteSlug:e.siteSlug,domainScope:e.domainScope,provider:e.provider,routingMode:e.routingMode,installationId:e.installationId,environment:d(e.domain).isLocalhost?`development`:`production`})}),r=await n.json();return n.ok===!1||r.status!==`success`||!r.data?.token?{success:!1,message:r.message??`This license is already active on another domain. Please deactivate it first.`}:{success:!0,buyer:r.data.buyer??`Customer`,token:r.data.token,domain:r.data.domain??d(e.domain).host}}catch{return{success:!1,message:`Failed to connect to the central registry. Please try again later.`}}}async function R(e,t,n,r,i,a=`envato`,o=fetch){let s=w();try{let c=await L({purchaseCode:e,domain:t,siteSlug:n,domainScope:r,routingMode:i,provider:a,installationId:s.installationId,fetchImpl:o});return c.success?{valid:!0,buyer:c.buyer,token:c.token,domain:c.domain,state:s}:{valid:!1,error:c.message}}catch{return{valid:!1,error:`Failed to verify license. Check your internet connection.`}}}const z=new Set([`/health`,`/api/v1/license/status`]);async function B(e={}){if(!(e.isPrimaryWorker??(!Bun.env.WORKER_ID||Bun.env.WORKER_ID===`0`)))return;let t=e.domain??`localhost`;if(e.onInvalidate&&ne(e.onInvalidate),m(t)){M(`valid`);return}let n=await E();if(!n?.instanceToken){M(e.isBootstrapComplete?`valid`:`unavailable`);return}if(e.signingKey&&!Z(n.instanceToken,t,{publicKeyPem:e.signingKey})){M(`invalid`,`domain-mismatch`);return}if(await W(e)>(m(t)?1/0:$(n.instanceToken))){M(`invalid`,`multi-site-unauthorized`);return}M(`valid`)}function V(e={}){B(e);let t=e.allowedPaths??z;return new a({name:`jchatRuntime`}).derive({as:`global`},()=>({runtimeStatus:N()})).onBeforeHandle({as:`global`},async({request:n,set:r})=>{if(n.method===`POST`&&n.url.includes(`/owner/sites`)){let t=e.domain??`localhost`,n=await E(),i=m(t)?1/0:$(n?.instanceToken);if(await W(e)>=i)return r.status=403,{status:`license_restricted`,message:`Site creation limit reached (${i} site${i===1?``:`s`} allowed on your license). Please upgrade your license to create additional sites.`,reference:`multi-site-unauthorized`}}return U(n,r,t)})}function H(e,t,n){return n.has(e)?!0:t===`invalid`?e===`/install/upgrade-license`:t===`unavailable`?e===`/install`||e.startsWith(`/install/`)||e.startsWith(`/assets/`)||e.startsWith(`/_`)||e===`/favicon.ico`:!1}function U(e,t,n=z,r=Bun.env.NODE_ENV===`production`){let{status:i,reference:a}=N(),o=e.headers.get(`host`)?.split(`:`)[0]?.toLowerCase();if(o&&f(o)&&m(Bun.env.JCHAT_DOMAIN||`localhost`))return t.status=403,{status:`license_invalid`,message:`Public domain deployment requires a valid license matching this domain.`,reference:`public-host-requires-license`};if(i!==`valid`&&i!==`unreachable-fallback`&&(r||i!==`unavailable`)&&!H(new URL(e.url).pathname.replace(/\/+$/,``)||`/`,i,n))return t.status=503,i===`unavailable`?{status:`license_unavailable`,message:`This JChat installation is not activated. Please complete the installation.`,reference:a}:{status:`license_invalid`,message:`This JChat installation is disabled because its license is invalid.`,reference:a}}async function W(e){let t=Bun.env.DATABASE_URL;if(t&&typeof Bun<`u`&&`SQL`in Bun)try{let e=new Bun.SQL(t),n=await e`SELECT count(*)::int as count FROM sites WHERE deleted_at IS NULL`;if(await e.close(),n?.[0]?.count!==void 0&&n[0].count!==null)return Number(n[0].count)}catch{}if(e.getSiteCount)try{return await e.getSiteCount()}catch{return 0}return 0}function G(t,n=`production`,r){let i={...t},a=!0;typeof i.JCHAT_COOKIE_SECRET!=`string`&&(i.JCHAT_COOKIE_SECRET=``);try{let t=T();if(n===`developer-sandbox`)a=!0;else if(!t)a=!1,n===`production`&&(i.JCHAT_COOKIE_SECRET=e.randomBytes(64).toString(`hex`));else{let o=typeof i.JCHAT_DOMAIN==`string`?i.JCHAT_DOMAIN:void 0,s=typeof i.NODE_ENV==`string`?i.NODE_ENV:void 0;if(!o||!p(o)||s===`production`&&!f(o))throw Error(`A valid installed JChat public domain is required for production deployments.`);if(!Z(t,o||`localhost`,{publicKeyPem:r}))a=!1,n===`production`&&(i.JCHAT_COOKIE_SECRET=e.randomBytes(64).toString(`hex`));else{let r=X(t);if(s===`production`&&r?.environment===`development`)a=!1,n===`production`&&(i.JCHAT_COOKIE_SECRET=e.randomBytes(64).toString(`hex`));else{let n=t.split(`.`),a=n[2]||``;if(a&&r){let t=e.createHmac(`sha256`,a).update(`${n[0]}.${n[1]}:${r.domain}:${r.installationId}`).digest(`hex`);i.JCHAT_COOKIE_SECRET+=t}}}}}catch{a=!1,n===`production`&&(i.JCHAT_COOKIE_SECRET=e.randomBytes(64).toString(`hex`))}return i.SYSTEM_BOOTSTRAP_COMPLETE=a,i}function re(e,t=`production`,n){return G(e,t,n)}function K(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function q(e){return typeof e==`string`&&e.trim().length>0}function J(e){if(!e)return null;try{return JSON.parse(Buffer.from(e,`base64url`).toString(`utf8`))}catch{return null}}function Y(e){let t=e.split(`.`);if(t.length!==3)return null;let n=J(t[0]);return!K(n)||n.alg!==`RS256`||n.typ!==`JWT`?null:{alg:`RS256`,typ:`JWT`}}function ie(e){if(!K(e))return null;let{iss:t,aud:n,licenseId:r,domain:i,buyer:a,installationId:o,plan:s,entitlements:c,purchaseProvider:l,environment:u,routingMode:p,iat:m,exp:h,isTrial:g,stages:_,channel:v,limits:y}=e;if(!q(t)||!q(n)||!q(r)||!q(i)||!q(a)||!q(o)||!q(s)||!Array.isArray(c)||!c.every(q)||l!==`envato`&&l!==`jchat`||u!==`production`&&u!==`development`||p!==`path`&&p!==`subdomain`||typeof m!=`number`||!Number.isSafeInteger(m)||m<0||h!==void 0&&(typeof h!=`number`||!Number.isSafeInteger(h)||h<0)||g!==void 0&&typeof g!=`boolean`)return null;let b=new Set([`stable`,`beta`,`experimental`]),x;if(_!==void 0){if(!Array.isArray(_)||!_.every(e=>typeof e==`string`&&b.has(e)))return null;x=_}let S=new Set([`stable`,`lts`]),C;if(v!==void 0){if(typeof v!=`string`||!S.has(v))return null;C=v}let w;if(y!==void 0){if(!K(y)||typeof y.maxSites!=`number`||!Number.isSafeInteger(y.maxSites))return null;w={maxSites:y.maxSites,...typeof y.maxRoomsPerSite==`number`&&Number.isSafeInteger(y.maxRoomsPerSite)?{maxRoomsPerSite:y.maxRoomsPerSite}:{}}}let T;try{T=d(i)}catch{return null}return u===`development`&&!T.isLocalhost||u===`production`&&!f(i)?null:{iss:t,aud:n,licenseId:r,domain:i,buyer:a,installationId:o,plan:s,entitlements:c,purchaseProvider:l,environment:u,routingMode:p,iat:m,...h===void 0?{}:{exp:h},...g===void 0?{}:{isTrial:g},...x===void 0?{}:{stages:x},...C===void 0?{}:{channel:C},...w===void 0?{}:{limits:w}}}function X(e){let t=e.split(`.`);return t.length!==3||!t.every(Boolean)||!Y(e)?null:ie(J(t[1]))}function Z(t,n,r){if(!t||t===`YOUR_LICENSE_KEY_PLACEHOLDER`)return!1;try{let i=t.split(`.`);if(i.length!==3||!Y(t))return!1;let a=X(t);if(!a)return!1;let o=r.issuer??Bun.env.JCHAT_LICENSE_ISSUER??`https://license.jchatcloud.com`,s=r.audience??Bun.env.JCHAT_LICENSE_AUDIENCE??`jchat-chat`;if(a.iss!==o||a.aud!==s)return!1;let c=d(n).host,l=d(a.domain).host;if(c!==l&&(a.routingMode!==`subdomain`||!c.endsWith(`.${l}`)))return!1;let u=Buffer.from(`${i[0]}.${i[1]}`),f=Buffer.from(i[2].replace(/-/g,`+`).replace(/_/g,`/`),`base64`);return e.verify(`sha256`,u,r.publicKeyPem,f)}catch{return!1}}function ae(e,t,n,r){if(r&&!Z(e,t,r))return!1;let i=X(e);return i?i.installationId===n:!1}function oe(e,t,n,r){return Z(e,t,r)?X(e)?.entitlements?.includes(n)??!1:!1}function se(e,t=`localhost`,n){if(n&&(!e||!Z(e,t,n))||!e)return!1;let r=X(e);return r?r.environment===`development`&&m(t)?!0:$(e)>1||(r.entitlements?.includes(`site.create.multi`)??!1):!1}function Q(e,t){return e?X(e)?.entitlements?.includes(t)??!1:!1}function ce(e,t){return t===`stable`?!0:e?(X(e)?.stages??[`stable`]).includes(t):!1}function $(e){return e?X(e)?.limits?.maxSites??1:1}function le(e){return e?X(e)?.channel??`stable`:`stable`}function ue(e){return $(e)>1||Q(e,`site.create.multi`)}export{c as DEFAULT_LICENSE_AUDIENCE,s as DEFAULT_LICENSE_ISSUER,o as DEFAULT_LICENSE_SERVER_URL,C as DEFAULT_STATE_PATH,L as activateRegistry,ue as canCreateMultiSite,w as createIdentity,b as findRepoRoot,$ as getMaxSites,le as getReleaseChannel,h as getRootDomain,N as getRuntimeStatus,Q as hasCapability,oe as hasEntitlement,ce as hasStageAccess,R as installAndActivate,p as isAllowedConfiguredDomain,P as isApplicationDisabled,m as isLocalhostDomain,g as isMatchingDomain,se as isMultiSiteAllowed,f as isPublicDomain,F as isRuntimeBlocked,V as jchatRuntime,re as loadServerContext,d as normalizeDomain,X as parsePayload,E as readState,T as readTokenSync,te as recordAudit,_ as resolveActivationDomain,S as resolveDataDir,v as resolveRuntimePaths,G as sealServerContext,M as setRuntimeStatus,B as startRuntimeSupervisor,ee as updateInstanceToken,ae as verifyEntitlement,Z as verifySignature,D as writeState};
|