@crewx/sdk 0.9.0-rc.117 → 0.9.0-rc.119
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/dist/account/env-bootstrap.d.ts +6 -0
- package/dist/account/index.d.ts +1 -1
- package/dist/account/index.js +2 -2
- package/dist/esm/account/index.js +2 -2
- package/dist/esm/index.js +174 -169
- package/dist/esm/plugins/index.js +6 -6
- package/dist/esm/publish/index.js +2 -2
- package/dist/esm/repository/index.js +29 -29
- package/dist/facade/Crewx.d.ts +2 -1
- package/dist/facade/task-ticket.d.ts +14 -0
- package/dist/index.browser.js +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +177 -172
- package/dist/mcp-app/projection.d.ts +1 -1
- package/dist/mcp-app/types.d.ts +1 -0
- package/dist/migrations/0032_ui_instance_opened_by.sql +1 -0
- package/dist/migrations/meta/_journal.json +8 -1
- package/dist/plugins/index.js +6 -6
- package/dist/publish/index.js +2 -2
- package/dist/repository/index.js +14 -14
- package/dist/schema/ui-instances.d.ts +19 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/ui-instance/index.d.ts +3 -3
- package/dist/ui-instance/json.d.ts +4 -1
- package/dist/ui-instance/store.d.ts +14 -4
- package/dist/ui-instance/types.d.ts +14 -4
- package/dist/ui-plugin/types.d.ts +2 -0
- package/dist/ui-plugin/validator.d.ts +1 -1
- package/package.json +1 -1
- package/templates/agents/default.yaml +10 -0
|
@@ -1,5 +1,11 @@
|
|
|
1
|
+
export declare const CREWX_TASK_TICKET_SECRET_ENV: "CREWX_TASK_TICKET_SECRET";
|
|
1
2
|
export interface CrewxEnvFileOptions {
|
|
2
3
|
workspaceDir?: string;
|
|
3
4
|
homeDir?: string;
|
|
4
5
|
}
|
|
6
|
+
export declare function resolveCrewxEnvFilePaths(options?: CrewxEnvFileOptions): {
|
|
7
|
+
workspace: string;
|
|
8
|
+
home: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function readCrewxEnvFileKeys(path: string): ReadonlySet<string>;
|
|
5
11
|
export declare function loadCrewxEnvFiles(options?: CrewxEnvFileOptions): void;
|
package/dist/account/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { ACCOUNT_BASE_URL_ENV, ACCOUNT_ISSUER_ENV, ACCOUNT_TARGET_ENV, DEFAULT_ACCEPTED_ISSUERS, LOCAL_TARGET, MARKETPLACE_DISABLED_ENV, MARKETPLACE_URL_ENV, PRODUCTION_TARGET, appendEndpoint, assertAccountTargetNotMixed, resolveAccountBaseUrl, resolveAccountTarget, resolveAcceptedAccountIssuers, resolveAccountIssuer, resolveMarketplaceUrl, } from './config';
|
|
2
2
|
export type { AccountTarget, AccountTargetProfile, AccountTargetSource, Environment, } from './config';
|
|
3
|
-
export { loadCrewxEnvFiles } from './env-bootstrap';
|
|
3
|
+
export { CREWX_TASK_TICKET_SECRET_ENV, loadCrewxEnvFiles, readCrewxEnvFileKeys, resolveCrewxEnvFilePaths, } from './env-bootstrap';
|
|
4
4
|
export type { CrewxEnvFileOptions } from './env-bootstrap';
|
|
5
5
|
export { AccountAuthError, AuthClientError, AuthError, AccountConfigurationError, AuthJsonValidationError, LoginRequiredError, SessionManagerError, } from './errors';
|
|
6
6
|
export type { AccountAuthErrorKind, AuthJsonValidationCode } from './errors';
|
package/dist/account/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var dotenv=require('dotenv'),T=require('path'),$=require('os'),z=require('fs'),crypto=require('crypto');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var T__namespace=/*#__PURE__*/_interopNamespace(T);var $__namespace=/*#__PURE__*/_interopNamespace($);var z__namespace=/*#__PURE__*/_interopNamespace(z);var s=class extends Error{code;kind;status;constructor(e,n,r,o){super(o??`Account authentication request failed (${e})`),this.name="AccountAuthError",this.code=e,this.kind=n,this.status=r;}};var l=class extends Error{code="LOGIN_REQUIRED";constructor(){super("Login required \u2014 please log in again"),this.name="LoginRequiredError";}},f=class extends Error{code;constructor(e,n){super(n),this.name="SessionManagerError",this.code=e;}},p=class extends Error{code;constructor(e,n="auth.json is invalid \u2014 please log in again"){super(n),this.name="AuthJsonValidationError",this.code=e;}},i=class extends s{constructor(e){let n=e.startsWith("ACCOUNT_BASE_URL")?"CREWX_ACCOUNT_BASE_URL":e.startsWith("ACCOUNT_ISSUER")?"CREWX_ACCOUNT_ISSUER":e==="ACCOUNT_TARGET_INVALID"?"CREWX_TARGET":e==="ACCOUNT_TARGET_MIXED"?"CREWX_ACCOUNT_BASE_URL/CREWX_MARKETPLACE_URL":e==="MARKETPLACE_DISABLED"?"CREWX_MARKETPLACE_DISABLED":"CREWX_MARKETPLACE_URL",r=e==="ACCOUNT_TARGET_MIXED"?`${n} must not mix loopback and public hosts \u2014 choose one account target`:e==="MARKETPLACE_DISABLED"?`${n} disables Marketplace access`:`${n} is missing or invalid \u2014 configure it and try again`;super(e,"configuration",void 0,r),this.name="AccountConfigurationError";}};var O="CREWX_ACCOUNT_BASE_URL",k="CREWX_ACCOUNT_ISSUER",v="CREWX_MARKETPLACE_URL",x="CREWX_TARGET",W="CREWX_MARKETPLACE_DISABLED",R=Object.freeze({accountBaseUrl:"https://app.sowonai.com",marketplaceUrl:"https://market.sowonai.com"}),S=Object.freeze({accountBaseUrl:"http://127.0.0.1:3030",marketplaceUrl:"http://127.0.0.1:4000"}),L=Object.freeze(["https://app.sowonai.com/auth/v1","https://auth.sowonai.com/auth/v1"]);function D(t,e,n=false){let r=t?.trim();if(!r)throw new i(e);try{let o=new URL(r);if(o.protocol!=="http:"&&o.protocol!=="https:"||o.username.length>0||o.password.length>0||o.hostname.length===0||o.search.length>0||o.hash.length>0||n&&o.pathname!=="/")throw new Error("invalid URL")}catch{throw new i(e)}return r.replace(/\/+$/,"")}function j(t){let e=t?.trim();if(!e)throw new i("ACCOUNT_ISSUER_INVALID");try{let n=new URL(e);if(n.protocol!=="http:"&&n.protocol!=="https:"||n.username.length>0||n.password.length>0||n.hostname.length===0||n.search.length>0||n.hash.length>0)throw new Error("invalid issuer")}catch{throw new i("ACCOUNT_ISSUER_INVALID")}return e}function P(t){let e=t[x];if(e===void 0)return "production";let n=e.trim();if(n==="local"||n==="production")return n;throw new i("ACCOUNT_TARGET_INVALID")}function X(t){let e=t[W]?.trim().toLowerCase();return e==="1"||e==="true"}function b(t){return t==="local"?S:R}function V(t=process.env){let e=P(t),n=t[O];return n!==void 0?D(n,"ACCOUNT_BASE_URL_INVALID",true):b(e).accountBaseUrl}function pe(t=process.env){let e=P(t);if(X(t))throw new i("MARKETPLACE_DISABLED");let n=t[v];return n!==void 0?D(n,"MARKETPLACE_URL_INVALID"):b(e).marketplaceUrl}function I(t=process.env){let e=t[k];return e===void 0?L:[j(e)]}function he(t=process.env){return I(t)[0]}function K(t,e,n,r=false){if(t===void 0)return e;try{return D(t,n,r)}catch{return t.trim()}}function le(t){let e=t[k];if(e===void 0)return L;try{return [j(e)]}catch{return [e.trim()]}}function q(t){if(t===null)return false;try{let e=new URL(t).hostname.toLowerCase();return e==="127.0.0.1"||e==="localhost"||e==="[::1]"||e==="::1"}catch{return false}}function fe(t,e){return e!==null&&t===R.accountBaseUrl&&e===R.marketplaceUrl?"production":e!==null&&t===S.accountBaseUrl&&e===S.marketplaceUrl?"local":"custom"}function F(t=process.env){let e,n=true;try{e=P(t);}catch{e="production",n=false;}let r=b(e),o=t[x]!==void 0&&n,a=t[O],m=t[v],u=X(t),d=K(a,r.accountBaseUrl,"ACCOUNT_BASE_URL_INVALID",true),y=u?null:K(m,r.marketplaceUrl,"MARKETPLACE_URL_INVALID");return {accountBaseUrl:d,marketplaceUrl:y,issuers:le(t),profile:fe(d,y),sources:{accountBaseUrl:a===void 0?o?"profile":"default":"env",marketplaceUrl:u?"disabled":m===void 0?o?"profile":"default":"env",issuer:t[k]===void 0?"default":"env"},mixed:y!==null&&q(d)!==q(y),marketplaceDisabled:u}}function de(t=process.env){if(F(t).mixed)throw new i("ACCOUNT_TARGET_MIXED")}function J(t,e){return `${t.replace(/\/+$/,"")}/${e.replace(/^\/+/,"")}`}function U(){if(process.env.CREWX_HOME){let t=T__namespace.resolve(process.env.CREWX_HOME);try{return z__namespace.realpathSync(t)}catch(e){if(e instanceof Error&&"code"in e&&e.code==="ENOENT")return t;throw e}}return process.platform!=="win32"&&process.env.XDG_CONFIG_HOME?T__namespace.join(process.env.XDG_CONFIG_HOME,"crewx"):T__namespace.join($__namespace.homedir(),".crewx")}function Ae(t={}){let e=t.workspaceDir??process.env.CREWX_WORKSPACE??process.cwd();dotenv.config({path:T.join(e,".env"),override:false,quiet:true});let n=t.homeDir??U();dotenv.config({path:T.join(n,".env"),override:false,quiet:true});}var ne="auth.json",B=2,te=["version","sub","email","access_token","refresh_token","expires_at","updated_at"];function h(t="auth.json is invalid \u2014 please log in again"){throw new p("AUTH_JSON_INVALID",t)}function ye(){throw new p("AUTH_JSON_LEGACY","auth.json uses an unsupported legacy format \u2014 please log in again")}function Re(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Se(t){try{return g(t),!0}catch{return false}}function g(t){if(!Re(t))return h();if(t.version===1)return ye();if(t.version!==B)return h();let e=Object.keys(t);if(e.length!==te.length||e.some(r=>!te.includes(r))||typeof t.sub!="string"||t.sub.length===0||typeof t.email!="string"||t.email.length===0||typeof t.access_token!="string"||t.access_token.length===0||typeof t.refresh_token!="string"||t.refresh_token.length===0)return h();let n=t.expires_at;return typeof n!="number"||!Number.isSafeInteger(n)||n<0||typeof t.updated_at!="string"||t.updated_at.length===0||Number.isNaN(Date.parse(t.updated_at))?h():{version:B,sub:t.sub,email:t.email,access_token:t.access_token,refresh_token:t.refresh_token,expires_at:n,updated_at:t.updated_at}}function re(t){let e;try{e=JSON.parse(t);}catch{return h()}return g(e)}function oe(t){return t??T.join(U(),ne)}var A=class{configuredPath;constructor(e={}){this.configuredPath=typeof e=="string"?e:e.filePath;}path(){return oe(this.configuredPath)}read(){let e=this.path();if(!z.existsSync(e))return null;try{return re(z.readFileSync(e,"utf8"))}catch(n){throw n instanceof p?n:new p("AUTH_JSON_INVALID")}}write(e){let n=g(e),r=this.path(),o=T.dirname(r);z.mkdirSync(o,{recursive:true,mode:448});let a=`${r}.tmp.${process.pid}.${crypto.randomUUID()}`;try{z.writeFileSync(a,JSON.stringify(n,null,2),{encoding:"utf8",mode:384}),z.chmodSync(a,384),z.renameSync(a,r),z.chmodSync(r,384);}catch{try{z.existsSync(a)&&z.unlinkSync(a);}catch{}throw new Error("Could not persist auth.json securely")}}clear(){let e=this.path();try{z.existsSync(e)&&z.unlinkSync(e);}catch{throw new Error("Could not clear auth.json")}}};function ke(t){let e=new A({filePath:t}).read();if(!e)throw new l;return e}function Ie(t,e){new A({filePath:e}).write(t);}function Ue(t){new A({filePath:t}).clear();}var ie="/auth/v1/oauth/device/code",ce="/auth/v1/oauth/token",ae="/auth/v1/oauth/revoke",N="crewx-cli",E="urn:ietf:params:oauth:grant-type:device_code";function c(t){return typeof t=="string"&&t.trim().length>0}function C(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)?t:null}function Ne(t){let e=C(t),n=e?.error??e?.code;if(typeof n=="string")return n.toLowerCase();let r=C(n),o=r?.code??r?.error;return typeof o=="string"?o.toLowerCase():void 0}function Oe(t){let e=C(t);if(!e||!c(e.device_code)||!c(e.user_code)||!c(e.verification_uri))throw new s("AUTH_RESPONSE_INVALID","protocol");let n=e.expires_in,r=e.interval;if(typeof n!="number"||!Number.isSafeInteger(n)||n<=0)throw new s("AUTH_RESPONSE_INVALID","protocol");if(e.verification_uri_complete!==void 0&&!c(e.verification_uri_complete))throw new s("AUTH_RESPONSE_INVALID","protocol");if(r!==void 0&&(typeof r!="number"||!Number.isSafeInteger(r)||r<0))throw new s("AUTH_RESPONSE_INVALID","protocol");let o={device_code:e.device_code,user_code:e.user_code,verification_uri:e.verification_uri,expires_in:n};return e.verification_uri_complete!==void 0&&(o.verification_uri_complete=e.verification_uri_complete),r!==void 0&&(o.interval=r),o}function ve(t){let e=C(t),n=C(e?.account),r=e?.expires_in;if(!e||!c(e.access_token)||!c(e.refresh_token)||typeof r!="number"||!Number.isSafeInteger(r)||r<=0||!n||!c(n.sub)||!c(n.email))throw new s("AUTH_RESPONSE_INVALID","protocol");let o={access_token:e.access_token,refresh_token:e.refresh_token,expires_in:r,account:{sub:n.sub,email:n.email}};return typeof e.token_type=="string"&&e.token_type.length>0&&(o.token_type=e.token_type),typeof e.scope=="string"&&e.scope.length>0&&(o.scope=e.scope),o}var w=class{configuredBaseUrl;fetchImpl;timeoutMs;constructor(e={}){let n=typeof e=="string"?{baseUrl:e}:e;this.configuredBaseUrl=n.baseUrl===void 0?void 0:xe(n.baseUrl),this.fetchImpl=n.fetch??n.fetchImpl,this.timeoutMs=n.timeoutMs??1e4;}baseUrl(){return this.configuredBaseUrl!==void 0?this.configuredBaseUrl:V()}signal(e){if(!(e<=0||typeof AbortSignal>"u"||typeof AbortSignal.timeout!="function"))return AbortSignal.timeout(e)}async request(e,n,r,o={}){let a=J(this.baseUrl(),e),m=this.fetchImpl??globalThis.fetch;if(typeof m!="function")throw new s("AUTH_NETWORK_ERROR","network");let u;try{u=await m(a,{...n,signal:n.signal??this.signal(o.timeoutMs??this.timeoutMs)});}catch{throw new s("AUTH_NETWORK_ERROR","network")}if(o.parseBody===false){if(!u.ok)throw se(u.status,null,r);return}let d=null;try{d=await u.json();}catch{d=null;}if(!u.ok)throw se(u.status,d,r);return d}async requestDeviceCode(){let e=new URLSearchParams;e.set("client_id",N);let n=await this.request(ie,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:e.toString()});return Oe(n)}async requestToken(e){Le(e);let n=new URLSearchParams;n.set("grant_type",e.grant_type),n.set("client_id",N),e.grant_type===E?n.set("device_code",e.device_code):n.set("refresh_token",e.refresh_token);let r=await this.request(ce,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:n.toString()},e);return ve(r)}async exchangeDeviceCode(e){return this.requestToken({grant_type:E,device_code:e})}async refreshToken(e){return this.requestToken({grant_type:"refresh_token",refresh_token:e})}async deviceCode(){return this.requestDeviceCode()}async getDeviceCode(){return this.requestDeviceCode()}async token(e){return this.requestToken(e)}async getToken(e){return this.requestToken(e)}async refresh(e){return this.refreshToken(e)}async refreshAccessToken(e){return this.refreshToken(e)}async revokeToken(e){if(!c(e))throw new s("AUTH_INPUT_INVALID","protocol");let n=new URLSearchParams;n.set("token",e),n.set("token_type_hint","refresh_token"),n.set("client_id",N),await this.request(ae,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:n.toString()},void 0,{parseBody:false,timeoutMs:3e3});}async revoke(e){return this.revokeToken(e)}};function xe(t){if(typeof t!="string"||!t.trim())throw new i("ACCOUNT_BASE_URL_INVALID");try{let e=new URL(t.trim());if(e.protocol!=="http:"&&e.protocol!=="https:"||e.username.length>0||e.password.length>0||e.hostname.length===0||e.pathname!=="/"||e.search.length>0||e.hash.length>0)throw new Error("invalid URL")}catch{throw new i("ACCOUNT_BASE_URL_INVALID")}return t.trim().replace(/\/+$/,"")}function Le(t){if(!t||t.grant_type!==E&&t.grant_type!=="refresh_token"||t.grant_type===E&&!c(t.device_code)||t.grant_type==="refresh_token"&&!c(t.refresh_token))throw new s("AUTH_INPUT_INVALID","protocol")}function se(t,e,n){let r=Ne(e);if(t>=500)return new s("AUTH_SERVER_ERROR","server",t);if(n?.grant_type==="refresh_token"&&(r==="invalid_grant"||t===401))return new s("INVALID_REFRESH_TOKEN","invalid_refresh",t);if(n?.grant_type===E){if(r==="authorization_pending")return new s("AUTHORIZATION_PENDING","pending",t);if(r==="slow_down")return new s("SLOW_DOWN","pending",t);if(r==="access_denied")return new s("ACCESS_DENIED","denied",t);if(r==="expired_token")return new s("EXPIRED_TOKEN","expired",t)}return new s("AUTH_HTTP_ERROR","http",t)}var G=class{client;store;refreshSkewSeconds;now;nowSecondsOverride;refreshPromise=null;constructor(e={},n){let r=Pe(e)?e:void 0,o=r?{}:e;this.client=r??o.client??o.authClient??new w,this.store=o.store??o.storage??n??new A,this.refreshSkewSeconds=o.refreshSkewSeconds??60,this.now=o.now??(()=>Date.now()),this.nowSecondsOverride=o.nowSeconds;}getSession(){return this.readSession()}isLoggedIn(){return this.readSession()!==null}async getAccessToken(){let e=this.requireSession();return e.expires_at>this.epochSeconds()+this.refreshSkewSeconds?e.access_token:(await this.refreshSession(e)).access_token}async getValidAccessToken(){return this.getAccessToken()}async getToken(){return this.getAccessToken()}async refresh(){return this.refreshSession(this.requireSession())}async loginWithDeviceCode(e){let n=await this.client.exchangeDeviceCode(e);return this.persistTokenResponse(n)}async login(e){return this.loginWithDeviceCode(e)}async setSession(e){return this.persistTokenResponse(e)}clear(){this.store.clear();}async withAccessToken(e){return e(await this.getAccessToken())}readSession(){try{let e=this.store.read();if(e===null)return null;let n=g(e);return ue(n.access_token,n.sub),n}catch(e){throw e instanceof p?new l:e}}requireSession(){let e=this.readSession();if(!e)throw new l;return e}epochSeconds(){return this.nowSecondsOverride?.()??Math.floor(this.now()/1e3)}refreshSession(e){if(this.refreshPromise)return this.refreshPromise;let n;return n=this.performRefresh(e).finally(()=>{this.refreshPromise===n&&(this.refreshPromise=null);}),this.refreshPromise=n,n}async performRefresh(e){try{let n=await this.client.refreshToken(e.refresh_token);return this.persistTokenResponse(n,e.sub)}catch(n){throw De(n)?(this.store.clear(),new l):n}}persistTokenResponse(e,n){let r=e?.account;if(!e||typeof e.access_token!="string"||e.access_token.length===0||typeof e.refresh_token!="string"||e.refresh_token.length===0||!Number.isSafeInteger(e.expires_in)||e.expires_in<=0||!r||typeof r.sub!="string"||r.sub.length===0||typeof r.email!="string"||r.email.length===0)throw new f("AUTH_RESPONSE_INVALID","Account token response is malformed");if(n!==void 0&&r.sub!==n)throw new f("ACCOUNT_SUB_MISMATCH","Account subject changed during token refresh \u2014 please log in again");ue(e.access_token,r.sub);let o=g({version:2,sub:r.sub,email:r.email,access_token:e.access_token,refresh_token:e.refresh_token,expires_at:this.epochSeconds()+e.expires_in,updated_at:new Date(this.now()).toISOString()});return this.store.write(o),o}};function De(t){return t instanceof s?t.kind==="invalid_refresh":typeof t=="object"&&t!==null&&(t.kind==="invalid_refresh"||t.code==="INVALID_REFRESH_TOKEN")}function Pe(t){return typeof t.exchangeDeviceCode=="function"&&typeof t.refreshToken=="function"}function ue(t,e){let n=I(),r=be(t);if(!n.includes(r.iss))throw new f("ACCOUNT_ISSUER_MISMATCH","Access token issuer does not match the configured account issuer \u2014 please log in again");if(r.sub!==e)throw new f("ACCOUNT_SUB_MISMATCH","Access token subject does not match the account session \u2014 please log in again")}function be(t){if(typeof t!="string")throw H();let e=t.split(".");if(e.length!==3||e.some(n=>!/^[A-Za-z0-9_-]+$/.test(n)))throw H();try{let n=JSON.parse(Buffer.from(e[1],"base64url").toString("utf8"));if(typeof n!="object"||n===null||Array.isArray(n)||typeof n.iss!="string"||n.iss.length===0||typeof n.sub!="string"||n.sub.length===0)throw new Error("missing identity claims");return {iss:n.iss,sub:n.sub}}catch{throw H()}}function H(){return new f("ACCESS_TOKEN_INVALID","Access token identity could not be verified \u2014 please log in again")}
|
|
2
|
-
exports.ACCOUNT_BASE_URL_ENV=
|
|
1
|
+
'use strict';var dotenv=require('dotenv'),z=require('fs'),T=require('path'),$=require('os'),crypto=require('crypto');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var z__namespace=/*#__PURE__*/_interopNamespace(z);var T__namespace=/*#__PURE__*/_interopNamespace(T);var $__namespace=/*#__PURE__*/_interopNamespace($);var s=class extends Error{code;kind;status;constructor(e,n,r,o){super(o??`Account authentication request failed (${e})`),this.name="AccountAuthError",this.code=e,this.kind=n,this.status=r;}};var l=class extends Error{code="LOGIN_REQUIRED";constructor(){super("Login required \u2014 please log in again"),this.name="LoginRequiredError";}},f=class extends Error{code;constructor(e,n){super(n),this.name="SessionManagerError",this.code=e;}},p=class extends Error{code;constructor(e,n="auth.json is invalid \u2014 please log in again"){super(n),this.name="AuthJsonValidationError",this.code=e;}},i=class extends s{constructor(e){let n=e.startsWith("ACCOUNT_BASE_URL")?"CREWX_ACCOUNT_BASE_URL":e.startsWith("ACCOUNT_ISSUER")?"CREWX_ACCOUNT_ISSUER":e==="ACCOUNT_TARGET_INVALID"?"CREWX_TARGET":e==="ACCOUNT_TARGET_MIXED"?"CREWX_ACCOUNT_BASE_URL/CREWX_MARKETPLACE_URL":e==="MARKETPLACE_DISABLED"?"CREWX_MARKETPLACE_DISABLED":"CREWX_MARKETPLACE_URL",r=e==="ACCOUNT_TARGET_MIXED"?`${n} must not mix loopback and public hosts \u2014 choose one account target`:e==="MARKETPLACE_DISABLED"?`${n} disables Marketplace access`:`${n} is missing or invalid \u2014 configure it and try again`;super(e,"configuration",void 0,r),this.name="AccountConfigurationError";}};var N="CREWX_ACCOUNT_BASE_URL",k="CREWX_ACCOUNT_ISSUER",O="CREWX_MARKETPLACE_URL",x="CREWX_TARGET",j="CREWX_MARKETPLACE_DISABLED",y=Object.freeze({accountBaseUrl:"https://app.sowonai.com",marketplaceUrl:"https://market.sowonai.com"}),R=Object.freeze({accountBaseUrl:"http://127.0.0.1:3030",marketplaceUrl:"http://127.0.0.1:4000"}),L=Object.freeze(["https://app.sowonai.com/auth/v1","https://auth.sowonai.com/auth/v1"]);function D(t,e,n=false){let r=t?.trim();if(!r)throw new i(e);try{let o=new URL(r);if(o.protocol!=="http:"&&o.protocol!=="https:"||o.username.length>0||o.password.length>0||o.hostname.length===0||o.search.length>0||o.hash.length>0||n&&o.pathname!=="/")throw new Error("invalid URL")}catch{throw new i(e)}return r.replace(/\/+$/,"")}function X(t){let e=t?.trim();if(!e)throw new i("ACCOUNT_ISSUER_INVALID");try{let n=new URL(e);if(n.protocol!=="http:"&&n.protocol!=="https:"||n.username.length>0||n.password.length>0||n.hostname.length===0||n.search.length>0||n.hash.length>0)throw new Error("invalid issuer")}catch{throw new i("ACCOUNT_ISSUER_INVALID")}return e}function P(t){let e=t[x];if(e===void 0)return "production";let n=e.trim();if(n==="local"||n==="production")return n;throw new i("ACCOUNT_TARGET_INVALID")}function q(t){let e=t[j]?.trim().toLowerCase();return e==="1"||e==="true"}function b(t){return t==="local"?R:y}function V(t=process.env){let e=P(t),n=t[N];return n!==void 0?D(n,"ACCOUNT_BASE_URL_INVALID",true):b(e).accountBaseUrl}function fe(t=process.env){let e=P(t);if(q(t))throw new i("MARKETPLACE_DISABLED");let n=t[O];return n!==void 0?D(n,"MARKETPLACE_URL_INVALID"):b(e).marketplaceUrl}function I(t=process.env){let e=t[k];return e===void 0?L:[X(e)]}function de(t=process.env){return I(t)[0]}function G(t,e,n,r=false){if(t===void 0)return e;try{return D(t,n,r)}catch{return t.trim()}}function Ae(t){let e=t[k];if(e===void 0)return L;try{return [X(e)]}catch{return [e.trim()]}}function W(t){if(t===null)return false;try{let e=new URL(t).hostname.toLowerCase();return e==="127.0.0.1"||e==="localhost"||e==="[::1]"||e==="::1"}catch{return false}}function _e(t,e){return e!==null&&t===y.accountBaseUrl&&e===y.marketplaceUrl?"production":e!==null&&t===R.accountBaseUrl&&e===R.marketplaceUrl?"local":"custom"}function F(t=process.env){let e,n=true;try{e=P(t);}catch{e="production",n=false;}let r=b(e),o=t[x]!==void 0&&n,c=t[N],m=t[O],u=q(t),d=G(c,r.accountBaseUrl,"ACCOUNT_BASE_URL_INVALID",true),S=u?null:G(m,r.marketplaceUrl,"MARKETPLACE_URL_INVALID");return {accountBaseUrl:d,marketplaceUrl:S,issuers:Ae(t),profile:_e(d,S),sources:{accountBaseUrl:c===void 0?o?"profile":"default":"env",marketplaceUrl:u?"disabled":m===void 0?o?"profile":"default":"env",issuer:t[k]===void 0?"default":"env"},mixed:S!==null&&W(d)!==W(S),marketplaceDisabled:u}}function ge(t=process.env){if(F(t).mixed)throw new i("ACCOUNT_TARGET_MIXED")}function J(t,e){return `${t.replace(/\/+$/,"")}/${e.replace(/^\/+/,"")}`}function U(){if(process.env.CREWX_HOME){let t=T__namespace.resolve(process.env.CREWX_HOME);try{return z__namespace.realpathSync(t)}catch(e){if(e instanceof Error&&"code"in e&&e.code==="ENOENT")return t;throw e}}return process.platform!=="win32"&&process.env.XDG_CONFIG_HOME?T__namespace.join(process.env.XDG_CONFIG_HOME,"crewx"):T__namespace.join($__namespace.homedir(),".crewx")}var ee="CREWX_TASK_TICKET_SECRET";function te(t={}){let e=t.workspaceDir??process.env.CREWX_WORKSPACE??process.cwd(),n=t.homeDir??U();return {workspace:T.join(e,".env"),home:T.join(n,".env")}}function Ee(t){try{return new Set(Object.keys(dotenv.parse(z.readFileSync(t))))}catch(e){if(e?.code==="ENOENT")return new Set;throw e}}function me(t){try{return dotenv.parse(z.readFileSync(t))}catch(e){if(e?.code==="ENOENT")return {};throw e}}function Te(t={}){let e=te(t);for(let n of [e.workspace,e.home]){let r=me(n);for(let[o,c]of Object.entries(r))o===ee||process.env[o]!==void 0||(process.env[o]=c);}}var se="auth.json",B=2,oe=["version","sub","email","access_token","refresh_token","expires_at","updated_at"];function h(t="auth.json is invalid \u2014 please log in again"){throw new p("AUTH_JSON_INVALID",t)}function Ue(){throw new p("AUTH_JSON_LEGACY","auth.json uses an unsupported legacy format \u2014 please log in again")}function ve(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Ne(t){try{return g(t),!0}catch{return false}}function g(t){if(!ve(t))return h();if(t.version===1)return Ue();if(t.version!==B)return h();let e=Object.keys(t);if(e.length!==oe.length||e.some(r=>!oe.includes(r))||typeof t.sub!="string"||t.sub.length===0||typeof t.email!="string"||t.email.length===0||typeof t.access_token!="string"||t.access_token.length===0||typeof t.refresh_token!="string"||t.refresh_token.length===0)return h();let n=t.expires_at;return typeof n!="number"||!Number.isSafeInteger(n)||n<0||typeof t.updated_at!="string"||t.updated_at.length===0||Number.isNaN(Date.parse(t.updated_at))?h():{version:B,sub:t.sub,email:t.email,access_token:t.access_token,refresh_token:t.refresh_token,expires_at:n,updated_at:t.updated_at}}function ie(t){let e;try{e=JSON.parse(t);}catch{return h()}return g(e)}function ce(t){return t??T.join(U(),se)}var A=class{configuredPath;constructor(e={}){this.configuredPath=typeof e=="string"?e:e.filePath;}path(){return ce(this.configuredPath)}read(){let e=this.path();if(!z.existsSync(e))return null;try{return ie(z.readFileSync(e,"utf8"))}catch(n){throw n instanceof p?n:new p("AUTH_JSON_INVALID")}}write(e){let n=g(e),r=this.path(),o=T.dirname(r);z.mkdirSync(o,{recursive:true,mode:448});let c=`${r}.tmp.${process.pid}.${crypto.randomUUID()}`;try{z.writeFileSync(c,JSON.stringify(n,null,2),{encoding:"utf8",mode:384}),z.chmodSync(c,384),z.renameSync(c,r),z.chmodSync(r,384);}catch{try{z.existsSync(c)&&z.unlinkSync(c);}catch{}throw new Error("Could not persist auth.json securely")}}clear(){let e=this.path();try{z.existsSync(e)&&z.unlinkSync(e);}catch{throw new Error("Could not clear auth.json")}}};function Oe(t){let e=new A({filePath:t}).read();if(!e)throw new l;return e}function xe(t,e){new A({filePath:e}).write(t);}function Le(t){new A({filePath:t}).clear();}var ue="/auth/v1/oauth/device/code",pe="/auth/v1/oauth/token",he="/auth/v1/oauth/revoke",v="crewx-cli",E="urn:ietf:params:oauth:grant-type:device_code";function a(t){return typeof t=="string"&&t.trim().length>0}function C(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)?t:null}function De(t){let e=C(t),n=e?.error??e?.code;if(typeof n=="string")return n.toLowerCase();let r=C(n),o=r?.code??r?.error;return typeof o=="string"?o.toLowerCase():void 0}function Pe(t){let e=C(t);if(!e||!a(e.device_code)||!a(e.user_code)||!a(e.verification_uri))throw new s("AUTH_RESPONSE_INVALID","protocol");let n=e.expires_in,r=e.interval;if(typeof n!="number"||!Number.isSafeInteger(n)||n<=0)throw new s("AUTH_RESPONSE_INVALID","protocol");if(e.verification_uri_complete!==void 0&&!a(e.verification_uri_complete))throw new s("AUTH_RESPONSE_INVALID","protocol");if(r!==void 0&&(typeof r!="number"||!Number.isSafeInteger(r)||r<0))throw new s("AUTH_RESPONSE_INVALID","protocol");let o={device_code:e.device_code,user_code:e.user_code,verification_uri:e.verification_uri,expires_in:n};return e.verification_uri_complete!==void 0&&(o.verification_uri_complete=e.verification_uri_complete),r!==void 0&&(o.interval=r),o}function be(t){let e=C(t),n=C(e?.account),r=e?.expires_in;if(!e||!a(e.access_token)||!a(e.refresh_token)||typeof r!="number"||!Number.isSafeInteger(r)||r<=0||!n||!a(n.sub)||!a(n.email))throw new s("AUTH_RESPONSE_INVALID","protocol");let o={access_token:e.access_token,refresh_token:e.refresh_token,expires_in:r,account:{sub:n.sub,email:n.email}};return typeof e.token_type=="string"&&e.token_type.length>0&&(o.token_type=e.token_type),typeof e.scope=="string"&&e.scope.length>0&&(o.scope=e.scope),o}var w=class{configuredBaseUrl;fetchImpl;timeoutMs;constructor(e={}){let n=typeof e=="string"?{baseUrl:e}:e;this.configuredBaseUrl=n.baseUrl===void 0?void 0:Ve(n.baseUrl),this.fetchImpl=n.fetch??n.fetchImpl,this.timeoutMs=n.timeoutMs??1e4;}baseUrl(){return this.configuredBaseUrl!==void 0?this.configuredBaseUrl:V()}signal(e){if(!(e<=0||typeof AbortSignal>"u"||typeof AbortSignal.timeout!="function"))return AbortSignal.timeout(e)}async request(e,n,r,o={}){let c=J(this.baseUrl(),e),m=this.fetchImpl??globalThis.fetch;if(typeof m!="function")throw new s("AUTH_NETWORK_ERROR","network");let u;try{u=await m(c,{...n,signal:n.signal??this.signal(o.timeoutMs??this.timeoutMs)});}catch{throw new s("AUTH_NETWORK_ERROR","network")}if(o.parseBody===false){if(!u.ok)throw ae(u.status,null,r);return}let d=null;try{d=await u.json();}catch{d=null;}if(!u.ok)throw ae(u.status,d,r);return d}async requestDeviceCode(){let e=new URLSearchParams;e.set("client_id",v);let n=await this.request(ue,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:e.toString()});return Pe(n)}async requestToken(e){Je(e);let n=new URLSearchParams;n.set("grant_type",e.grant_type),n.set("client_id",v),e.grant_type===E?n.set("device_code",e.device_code):n.set("refresh_token",e.refresh_token);let r=await this.request(pe,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:n.toString()},e);return be(r)}async exchangeDeviceCode(e){return this.requestToken({grant_type:E,device_code:e})}async refreshToken(e){return this.requestToken({grant_type:"refresh_token",refresh_token:e})}async deviceCode(){return this.requestDeviceCode()}async getDeviceCode(){return this.requestDeviceCode()}async token(e){return this.requestToken(e)}async getToken(e){return this.requestToken(e)}async refresh(e){return this.refreshToken(e)}async refreshAccessToken(e){return this.refreshToken(e)}async revokeToken(e){if(!a(e))throw new s("AUTH_INPUT_INVALID","protocol");let n=new URLSearchParams;n.set("token",e),n.set("token_type_hint","refresh_token"),n.set("client_id",v),await this.request(he,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:n.toString()},void 0,{parseBody:false,timeoutMs:3e3});}async revoke(e){return this.revokeToken(e)}};function Ve(t){if(typeof t!="string"||!t.trim())throw new i("ACCOUNT_BASE_URL_INVALID");try{let e=new URL(t.trim());if(e.protocol!=="http:"&&e.protocol!=="https:"||e.username.length>0||e.password.length>0||e.hostname.length===0||e.pathname!=="/"||e.search.length>0||e.hash.length>0)throw new Error("invalid URL")}catch{throw new i("ACCOUNT_BASE_URL_INVALID")}return t.trim().replace(/\/+$/,"")}function Je(t){if(!t||t.grant_type!==E&&t.grant_type!=="refresh_token"||t.grant_type===E&&!a(t.device_code)||t.grant_type==="refresh_token"&&!a(t.refresh_token))throw new s("AUTH_INPUT_INVALID","protocol")}function ae(t,e,n){let r=De(e);if(t>=500)return new s("AUTH_SERVER_ERROR","server",t);if(n?.grant_type==="refresh_token"&&(r==="invalid_grant"||t===401))return new s("INVALID_REFRESH_TOKEN","invalid_refresh",t);if(n?.grant_type===E){if(r==="authorization_pending")return new s("AUTHORIZATION_PENDING","pending",t);if(r==="slow_down")return new s("SLOW_DOWN","pending",t);if(r==="access_denied")return new s("ACCESS_DENIED","denied",t);if(r==="expired_token")return new s("EXPIRED_TOKEN","expired",t)}return new s("AUTH_HTTP_ERROR","http",t)}var K=class{client;store;refreshSkewSeconds;now;nowSecondsOverride;refreshPromise=null;constructor(e={},n){let r=Be(e)?e:void 0,o=r?{}:e;this.client=r??o.client??o.authClient??new w,this.store=o.store??o.storage??n??new A,this.refreshSkewSeconds=o.refreshSkewSeconds??60,this.now=o.now??(()=>Date.now()),this.nowSecondsOverride=o.nowSeconds;}getSession(){return this.readSession()}isLoggedIn(){return this.readSession()!==null}async getAccessToken(){let e=this.requireSession();return e.expires_at>this.epochSeconds()+this.refreshSkewSeconds?e.access_token:(await this.refreshSession(e)).access_token}async getValidAccessToken(){return this.getAccessToken()}async getToken(){return this.getAccessToken()}async refresh(){return this.refreshSession(this.requireSession())}async loginWithDeviceCode(e){let n=await this.client.exchangeDeviceCode(e);return this.persistTokenResponse(n)}async login(e){return this.loginWithDeviceCode(e)}async setSession(e){return this.persistTokenResponse(e)}clear(){this.store.clear();}async withAccessToken(e){return e(await this.getAccessToken())}readSession(){try{let e=this.store.read();if(e===null)return null;let n=g(e);return le(n.access_token,n.sub),n}catch(e){throw e instanceof p?new l:e}}requireSession(){let e=this.readSession();if(!e)throw new l;return e}epochSeconds(){return this.nowSecondsOverride?.()??Math.floor(this.now()/1e3)}refreshSession(e){if(this.refreshPromise)return this.refreshPromise;let n;return n=this.performRefresh(e).finally(()=>{this.refreshPromise===n&&(this.refreshPromise=null);}),this.refreshPromise=n,n}async performRefresh(e){try{let n=await this.client.refreshToken(e.refresh_token);return this.persistTokenResponse(n,e.sub)}catch(n){throw Me(n)?(this.store.clear(),new l):n}}persistTokenResponse(e,n){let r=e?.account;if(!e||typeof e.access_token!="string"||e.access_token.length===0||typeof e.refresh_token!="string"||e.refresh_token.length===0||!Number.isSafeInteger(e.expires_in)||e.expires_in<=0||!r||typeof r.sub!="string"||r.sub.length===0||typeof r.email!="string"||r.email.length===0)throw new f("AUTH_RESPONSE_INVALID","Account token response is malformed");if(n!==void 0&&r.sub!==n)throw new f("ACCOUNT_SUB_MISMATCH","Account subject changed during token refresh \u2014 please log in again");le(e.access_token,r.sub);let o=g({version:2,sub:r.sub,email:r.email,access_token:e.access_token,refresh_token:e.refresh_token,expires_at:this.epochSeconds()+e.expires_in,updated_at:new Date(this.now()).toISOString()});return this.store.write(o),o}};function Me(t){return t instanceof s?t.kind==="invalid_refresh":typeof t=="object"&&t!==null&&(t.kind==="invalid_refresh"||t.code==="INVALID_REFRESH_TOKEN")}function Be(t){return typeof t.exchangeDeviceCode=="function"&&typeof t.refreshToken=="function"}function le(t,e){let n=I(),r=He(t);if(!n.includes(r.iss))throw new f("ACCOUNT_ISSUER_MISMATCH","Access token issuer does not match the configured account issuer \u2014 please log in again");if(r.sub!==e)throw new f("ACCOUNT_SUB_MISMATCH","Access token subject does not match the account session \u2014 please log in again")}function He(t){if(typeof t!="string")throw H();let e=t.split(".");if(e.length!==3||e.some(n=>!/^[A-Za-z0-9_-]+$/.test(n)))throw H();try{let n=JSON.parse(Buffer.from(e[1],"base64url").toString("utf8"));if(typeof n!="object"||n===null||Array.isArray(n)||typeof n.iss!="string"||n.iss.length===0||typeof n.sub!="string"||n.sub.length===0)throw new Error("missing identity claims");return {iss:n.iss,sub:n.sub}}catch{throw H()}}function H(){return new f("ACCESS_TOKEN_INVALID","Access token identity could not be verified \u2014 please log in again")}
|
|
2
|
+
exports.ACCOUNT_BASE_URL_ENV=N;exports.ACCOUNT_ISSUER_ENV=k;exports.ACCOUNT_TARGET_ENV=x;exports.AUTH_JSON_FILENAME=se;exports.AUTH_JSON_VERSION=B;exports.AccountAuthError=s;exports.AccountConfigurationError=i;exports.AuthClient=w;exports.AuthClientError=s;exports.AuthError=s;exports.AuthJsonStore=A;exports.AuthJsonValidationError=p;exports.CREWX_TASK_TICKET_SECRET_ENV=ee;exports.DEFAULT_ACCEPTED_ISSUERS=L;exports.DEVICE_CODE_GRANT_TYPE=E;exports.DEVICE_CODE_PATH=ue;exports.LOCAL_TARGET=R;exports.LoginRequiredError=l;exports.MARKETPLACE_DISABLED_ENV=j;exports.MARKETPLACE_URL_ENV=O;exports.OAUTH_CLIENT_ID=v;exports.PRODUCTION_TARGET=y;exports.REVOKE_PATH=he;exports.SessionManager=K;exports.SessionManagerError=f;exports.TOKEN_PATH=pe;exports.appendEndpoint=J;exports.assertAccountTargetNotMixed=ge;exports.authJsonPath=ce;exports.clearAuthJson=Le;exports.isAuthJsonV2=Ne;exports.loadCrewxEnvFiles=Te;exports.parseAuthJson=ie;exports.readAuthJson=Oe;exports.readCrewxEnvFileKeys=Ee;exports.resolveAcceptedAccountIssuers=I;exports.resolveAccountBaseUrl=V;exports.resolveAccountIssuer=de;exports.resolveAccountTarget=F;exports.resolveCrewxEnvFilePaths=te;exports.resolveMarketplaceUrl=fe;exports.validateAuthJson=g;exports.writeAuthJson=xe;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {config}from'dotenv';import*as C from'path';import {join,dirname}from'path';import*as z from'os';import*as Y from'fs';import {existsSync,readFileSync,mkdirSync,writeFileSync,chmodSync,renameSync,unlinkSync}from'fs';import {randomUUID}from'crypto';var s=class extends Error{code;kind;status;constructor(e,n,r,o){super(o??`Account authentication request failed (${e})`),this.name="AccountAuthError",this.code=e,this.kind=n,this.status=r;}};var l=class extends Error{code="LOGIN_REQUIRED";constructor(){super("Login required \u2014 please log in again"),this.name="LoginRequiredError";}},f=class extends Error{code;constructor(e,n){super(n),this.name="SessionManagerError",this.code=e;}},p=class extends Error{code;constructor(e,n="auth.json is invalid \u2014 please log in again"){super(n),this.name="AuthJsonValidationError",this.code=e;}},i=class extends s{constructor(e){let n=e.startsWith("ACCOUNT_BASE_URL")?"CREWX_ACCOUNT_BASE_URL":e.startsWith("ACCOUNT_ISSUER")?"CREWX_ACCOUNT_ISSUER":e==="ACCOUNT_TARGET_INVALID"?"CREWX_TARGET":e==="ACCOUNT_TARGET_MIXED"?"CREWX_ACCOUNT_BASE_URL/CREWX_MARKETPLACE_URL":e==="MARKETPLACE_DISABLED"?"CREWX_MARKETPLACE_DISABLED":"CREWX_MARKETPLACE_URL",r=e==="ACCOUNT_TARGET_MIXED"?`${n} must not mix loopback and public hosts \u2014 choose one account target`:e==="MARKETPLACE_DISABLED"?`${n} disables Marketplace access`:`${n} is missing or invalid \u2014 configure it and try again`;super(e,"configuration",void 0,r),this.name="AccountConfigurationError";}};var v="CREWX_ACCOUNT_BASE_URL",I="CREWX_ACCOUNT_ISSUER",x="CREWX_MARKETPLACE_URL",L="CREWX_TARGET",j="CREWX_MARKETPLACE_DISABLED",S=Object.freeze({accountBaseUrl:"https://app.sowonai.com",marketplaceUrl:"https://market.sowonai.com"}),k=Object.freeze({accountBaseUrl:"http://127.0.0.1:3030",marketplaceUrl:"http://127.0.0.1:4000"}),D=Object.freeze(["https://app.sowonai.com/auth/v1","https://auth.sowonai.com/auth/v1"]);function P(t,e,n=false){let r=t?.trim();if(!r)throw new i(e);try{let o=new URL(r);if(o.protocol!=="http:"&&o.protocol!=="https:"||o.username.length>0||o.password.length>0||o.hostname.length===0||o.search.length>0||o.hash.length>0||n&&o.pathname!=="/")throw new Error("invalid URL")}catch{throw new i(e)}return r.replace(/\/+$/,"")}function X(t){let e=t?.trim();if(!e)throw new i("ACCOUNT_ISSUER_INVALID");try{let n=new URL(e);if(n.protocol!=="http:"&&n.protocol!=="https:"||n.username.length>0||n.password.length>0||n.hostname.length===0||n.search.length>0||n.hash.length>0)throw new Error("invalid issuer")}catch{throw new i("ACCOUNT_ISSUER_INVALID")}return e}function b(t){let e=t[L];if(e===void 0)return "production";let n=e.trim();if(n==="local"||n==="production")return n;throw new i("ACCOUNT_TARGET_INVALID")}function F(t){let e=t[j]?.trim().toLowerCase();return e==="1"||e==="true"}function V(t){return t==="local"?k:S}function J(t=process.env){let e=b(t),n=t[v];return n!==void 0?P(n,"ACCOUNT_BASE_URL_INVALID",true):V(e).accountBaseUrl}function he(t=process.env){let e=b(t);if(F(t))throw new i("MARKETPLACE_DISABLED");let n=t[x];return n!==void 0?P(n,"MARKETPLACE_URL_INVALID"):V(e).marketplaceUrl}function U(t=process.env){let e=t[I];return e===void 0?D:[X(e)]}function le(t=process.env){return U(t)[0]}function q(t,e,n,r=false){if(t===void 0)return e;try{return P(t,n,r)}catch{return t.trim()}}function fe(t){let e=t[I];if(e===void 0)return D;try{return [X(e)]}catch{return [e.trim()]}}function W(t){if(t===null)return false;try{let e=new URL(t).hostname.toLowerCase();return e==="127.0.0.1"||e==="localhost"||e==="[::1]"||e==="::1"}catch{return false}}function de(t,e){return e!==null&&t===S.accountBaseUrl&&e===S.marketplaceUrl?"production":e!==null&&t===k.accountBaseUrl&&e===k.marketplaceUrl?"local":"custom"}function $(t=process.env){let e,n=true;try{e=b(t);}catch{e="production",n=false;}let r=V(e),o=t[L]!==void 0&&n,a=t[v],T=t[x],u=F(t),d=q(a,r.accountBaseUrl,"ACCOUNT_BASE_URL_INVALID",true),R=u?null:q(T,r.marketplaceUrl,"MARKETPLACE_URL_INVALID");return {accountBaseUrl:d,marketplaceUrl:R,issuers:fe(t),profile:de(d,R),sources:{accountBaseUrl:a===void 0?o?"profile":"default":"env",marketplaceUrl:u?"disabled":T===void 0?o?"profile":"default":"env",issuer:t[I]===void 0?"default":"env"},mixed:R!==null&&W(d)!==W(R),marketplaceDisabled:u}}function Ae(t=process.env){if($(t).mixed)throw new i("ACCOUNT_TARGET_MIXED")}function M(t,e){return `${t.replace(/\/+$/,"")}/${e.replace(/^\/+/,"")}`}function N(){if(process.env.CREWX_HOME){let t=C.resolve(process.env.CREWX_HOME);try{return Y.realpathSync(t)}catch(e){if(e instanceof Error&&"code"in e&&e.code==="ENOENT")return t;throw e}}return process.platform!=="win32"&&process.env.XDG_CONFIG_HOME?C.join(process.env.XDG_CONFIG_HOME,"crewx"):C.join(z.homedir(),".crewx")}function _e(t={}){let e=t.workspaceDir??process.env.CREWX_WORKSPACE??process.cwd();config({path:join(e,".env"),override:false,quiet:true});let n=t.homeDir??N();config({path:join(n,".env"),override:false,quiet:true});}var re="auth.json",H=2,ne=["version","sub","email","access_token","refresh_token","expires_at","updated_at"];function h(t="auth.json is invalid \u2014 please log in again"){throw new p("AUTH_JSON_INVALID",t)}function Re(){throw new p("AUTH_JSON_LEGACY","auth.json uses an unsupported legacy format \u2014 please log in again")}function Se(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function ke(t){try{return E(t),!0}catch{return false}}function E(t){if(!Se(t))return h();if(t.version===1)return Re();if(t.version!==H)return h();let e=Object.keys(t);if(e.length!==ne.length||e.some(r=>!ne.includes(r))||typeof t.sub!="string"||t.sub.length===0||typeof t.email!="string"||t.email.length===0||typeof t.access_token!="string"||t.access_token.length===0||typeof t.refresh_token!="string"||t.refresh_token.length===0)return h();let n=t.expires_at;return typeof n!="number"||!Number.isSafeInteger(n)||n<0||typeof t.updated_at!="string"||t.updated_at.length===0||Number.isNaN(Date.parse(t.updated_at))?h():{version:H,sub:t.sub,email:t.email,access_token:t.access_token,refresh_token:t.refresh_token,expires_at:n,updated_at:t.updated_at}}function oe(t){let e;try{e=JSON.parse(t);}catch{return h()}return E(e)}function se(t){return t??join(N(),re)}var A=class{configuredPath;constructor(e={}){this.configuredPath=typeof e=="string"?e:e.filePath;}path(){return se(this.configuredPath)}read(){let e=this.path();if(!existsSync(e))return null;try{return oe(readFileSync(e,"utf8"))}catch(n){throw n instanceof p?n:new p("AUTH_JSON_INVALID")}}write(e){let n=E(e),r=this.path(),o=dirname(r);mkdirSync(o,{recursive:true,mode:448});let a=`${r}.tmp.${process.pid}.${randomUUID()}`;try{writeFileSync(a,JSON.stringify(n,null,2),{encoding:"utf8",mode:384}),chmodSync(a,384),renameSync(a,r),chmodSync(r,384);}catch{try{existsSync(a)&&unlinkSync(a);}catch{}throw new Error("Could not persist auth.json securely")}}clear(){let e=this.path();try{existsSync(e)&&unlinkSync(e);}catch{throw new Error("Could not clear auth.json")}}};function Ie(t){let e=new A({filePath:t}).read();if(!e)throw new l;return e}function Ue(t,e){new A({filePath:e}).write(t);}function Ne(t){new A({filePath:t}).clear();}var ce="/auth/v1/oauth/device/code",ae="/auth/v1/oauth/token",ue="/auth/v1/oauth/revoke",O="crewx-cli",m="urn:ietf:params:oauth:grant-type:device_code";function c(t){return typeof t=="string"&&t.trim().length>0}function w(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)?t:null}function Oe(t){let e=w(t),n=e?.error??e?.code;if(typeof n=="string")return n.toLowerCase();let r=w(n),o=r?.code??r?.error;return typeof o=="string"?o.toLowerCase():void 0}function ve(t){let e=w(t);if(!e||!c(e.device_code)||!c(e.user_code)||!c(e.verification_uri))throw new s("AUTH_RESPONSE_INVALID","protocol");let n=e.expires_in,r=e.interval;if(typeof n!="number"||!Number.isSafeInteger(n)||n<=0)throw new s("AUTH_RESPONSE_INVALID","protocol");if(e.verification_uri_complete!==void 0&&!c(e.verification_uri_complete))throw new s("AUTH_RESPONSE_INVALID","protocol");if(r!==void 0&&(typeof r!="number"||!Number.isSafeInteger(r)||r<0))throw new s("AUTH_RESPONSE_INVALID","protocol");let o={device_code:e.device_code,user_code:e.user_code,verification_uri:e.verification_uri,expires_in:n};return e.verification_uri_complete!==void 0&&(o.verification_uri_complete=e.verification_uri_complete),r!==void 0&&(o.interval=r),o}function xe(t){let e=w(t),n=w(e?.account),r=e?.expires_in;if(!e||!c(e.access_token)||!c(e.refresh_token)||typeof r!="number"||!Number.isSafeInteger(r)||r<=0||!n||!c(n.sub)||!c(n.email))throw new s("AUTH_RESPONSE_INVALID","protocol");let o={access_token:e.access_token,refresh_token:e.refresh_token,expires_in:r,account:{sub:n.sub,email:n.email}};return typeof e.token_type=="string"&&e.token_type.length>0&&(o.token_type=e.token_type),typeof e.scope=="string"&&e.scope.length>0&&(o.scope=e.scope),o}var y=class{configuredBaseUrl;fetchImpl;timeoutMs;constructor(e={}){let n=typeof e=="string"?{baseUrl:e}:e;this.configuredBaseUrl=n.baseUrl===void 0?void 0:Le(n.baseUrl),this.fetchImpl=n.fetch??n.fetchImpl,this.timeoutMs=n.timeoutMs??1e4;}baseUrl(){return this.configuredBaseUrl!==void 0?this.configuredBaseUrl:J()}signal(e){if(!(e<=0||typeof AbortSignal>"u"||typeof AbortSignal.timeout!="function"))return AbortSignal.timeout(e)}async request(e,n,r,o={}){let a=M(this.baseUrl(),e),T=this.fetchImpl??globalThis.fetch;if(typeof T!="function")throw new s("AUTH_NETWORK_ERROR","network");let u;try{u=await T(a,{...n,signal:n.signal??this.signal(o.timeoutMs??this.timeoutMs)});}catch{throw new s("AUTH_NETWORK_ERROR","network")}if(o.parseBody===false){if(!u.ok)throw ie(u.status,null,r);return}let d=null;try{d=await u.json();}catch{d=null;}if(!u.ok)throw ie(u.status,d,r);return d}async requestDeviceCode(){let e=new URLSearchParams;e.set("client_id",O);let n=await this.request(ce,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:e.toString()});return ve(n)}async requestToken(e){De(e);let n=new URLSearchParams;n.set("grant_type",e.grant_type),n.set("client_id",O),e.grant_type===m?n.set("device_code",e.device_code):n.set("refresh_token",e.refresh_token);let r=await this.request(ae,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:n.toString()},e);return xe(r)}async exchangeDeviceCode(e){return this.requestToken({grant_type:m,device_code:e})}async refreshToken(e){return this.requestToken({grant_type:"refresh_token",refresh_token:e})}async deviceCode(){return this.requestDeviceCode()}async getDeviceCode(){return this.requestDeviceCode()}async token(e){return this.requestToken(e)}async getToken(e){return this.requestToken(e)}async refresh(e){return this.refreshToken(e)}async refreshAccessToken(e){return this.refreshToken(e)}async revokeToken(e){if(!c(e))throw new s("AUTH_INPUT_INVALID","protocol");let n=new URLSearchParams;n.set("token",e),n.set("token_type_hint","refresh_token"),n.set("client_id",O),await this.request(ue,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:n.toString()},void 0,{parseBody:false,timeoutMs:3e3});}async revoke(e){return this.revokeToken(e)}};function Le(t){if(typeof t!="string"||!t.trim())throw new i("ACCOUNT_BASE_URL_INVALID");try{let e=new URL(t.trim());if(e.protocol!=="http:"&&e.protocol!=="https:"||e.username.length>0||e.password.length>0||e.hostname.length===0||e.pathname!=="/"||e.search.length>0||e.hash.length>0)throw new Error("invalid URL")}catch{throw new i("ACCOUNT_BASE_URL_INVALID")}return t.trim().replace(/\/+$/,"")}function De(t){if(!t||t.grant_type!==m&&t.grant_type!=="refresh_token"||t.grant_type===m&&!c(t.device_code)||t.grant_type==="refresh_token"&&!c(t.refresh_token))throw new s("AUTH_INPUT_INVALID","protocol")}function ie(t,e,n){let r=Oe(e);if(t>=500)return new s("AUTH_SERVER_ERROR","server",t);if(n?.grant_type==="refresh_token"&&(r==="invalid_grant"||t===401))return new s("INVALID_REFRESH_TOKEN","invalid_refresh",t);if(n?.grant_type===m){if(r==="authorization_pending")return new s("AUTHORIZATION_PENDING","pending",t);if(r==="slow_down")return new s("SLOW_DOWN","pending",t);if(r==="access_denied")return new s("ACCESS_DENIED","denied",t);if(r==="expired_token")return new s("EXPIRED_TOKEN","expired",t)}return new s("AUTH_HTTP_ERROR","http",t)}var K=class{client;store;refreshSkewSeconds;now;nowSecondsOverride;refreshPromise=null;constructor(e={},n){let r=be(e)?e:void 0,o=r?{}:e;this.client=r??o.client??o.authClient??new y,this.store=o.store??o.storage??n??new A,this.refreshSkewSeconds=o.refreshSkewSeconds??60,this.now=o.now??(()=>Date.now()),this.nowSecondsOverride=o.nowSeconds;}getSession(){return this.readSession()}isLoggedIn(){return this.readSession()!==null}async getAccessToken(){let e=this.requireSession();return e.expires_at>this.epochSeconds()+this.refreshSkewSeconds?e.access_token:(await this.refreshSession(e)).access_token}async getValidAccessToken(){return this.getAccessToken()}async getToken(){return this.getAccessToken()}async refresh(){return this.refreshSession(this.requireSession())}async loginWithDeviceCode(e){let n=await this.client.exchangeDeviceCode(e);return this.persistTokenResponse(n)}async login(e){return this.loginWithDeviceCode(e)}async setSession(e){return this.persistTokenResponse(e)}clear(){this.store.clear();}async withAccessToken(e){return e(await this.getAccessToken())}readSession(){try{let e=this.store.read();if(e===null)return null;let n=E(e);return pe(n.access_token,n.sub),n}catch(e){throw e instanceof p?new l:e}}requireSession(){let e=this.readSession();if(!e)throw new l;return e}epochSeconds(){return this.nowSecondsOverride?.()??Math.floor(this.now()/1e3)}refreshSession(e){if(this.refreshPromise)return this.refreshPromise;let n;return n=this.performRefresh(e).finally(()=>{this.refreshPromise===n&&(this.refreshPromise=null);}),this.refreshPromise=n,n}async performRefresh(e){try{let n=await this.client.refreshToken(e.refresh_token);return this.persistTokenResponse(n,e.sub)}catch(n){throw Pe(n)?(this.store.clear(),new l):n}}persistTokenResponse(e,n){let r=e?.account;if(!e||typeof e.access_token!="string"||e.access_token.length===0||typeof e.refresh_token!="string"||e.refresh_token.length===0||!Number.isSafeInteger(e.expires_in)||e.expires_in<=0||!r||typeof r.sub!="string"||r.sub.length===0||typeof r.email!="string"||r.email.length===0)throw new f("AUTH_RESPONSE_INVALID","Account token response is malformed");if(n!==void 0&&r.sub!==n)throw new f("ACCOUNT_SUB_MISMATCH","Account subject changed during token refresh \u2014 please log in again");pe(e.access_token,r.sub);let o=E({version:2,sub:r.sub,email:r.email,access_token:e.access_token,refresh_token:e.refresh_token,expires_at:this.epochSeconds()+e.expires_in,updated_at:new Date(this.now()).toISOString()});return this.store.write(o),o}};function Pe(t){return t instanceof s?t.kind==="invalid_refresh":typeof t=="object"&&t!==null&&(t.kind==="invalid_refresh"||t.code==="INVALID_REFRESH_TOKEN")}function be(t){return typeof t.exchangeDeviceCode=="function"&&typeof t.refreshToken=="function"}function pe(t,e){let n=U(),r=Ve(t);if(!n.includes(r.iss))throw new f("ACCOUNT_ISSUER_MISMATCH","Access token issuer does not match the configured account issuer \u2014 please log in again");if(r.sub!==e)throw new f("ACCOUNT_SUB_MISMATCH","Access token subject does not match the account session \u2014 please log in again")}function Ve(t){if(typeof t!="string")throw G();let e=t.split(".");if(e.length!==3||e.some(n=>!/^[A-Za-z0-9_-]+$/.test(n)))throw G();try{let n=JSON.parse(Buffer.from(e[1],"base64url").toString("utf8"));if(typeof n!="object"||n===null||Array.isArray(n)||typeof n.iss!="string"||n.iss.length===0||typeof n.sub!="string"||n.sub.length===0)throw new Error("missing identity claims");return {iss:n.iss,sub:n.sub}}catch{throw G()}}function G(){return new f("ACCESS_TOKEN_INVALID","Access token identity could not be verified \u2014 please log in again")}
|
|
2
|
-
export{
|
|
1
|
+
import {parse}from'dotenv';import*as Y from'fs';import {readFileSync,existsSync,mkdirSync,writeFileSync,chmodSync,renameSync,unlinkSync}from'fs';import*as C from'path';import {join,dirname}from'path';import*as z from'os';import {randomUUID}from'crypto';var s=class extends Error{code;kind;status;constructor(e,n,r,o){super(o??`Account authentication request failed (${e})`),this.name="AccountAuthError",this.code=e,this.kind=n,this.status=r;}};var l=class extends Error{code="LOGIN_REQUIRED";constructor(){super("Login required \u2014 please log in again"),this.name="LoginRequiredError";}},f=class extends Error{code;constructor(e,n){super(n),this.name="SessionManagerError",this.code=e;}},p=class extends Error{code;constructor(e,n="auth.json is invalid \u2014 please log in again"){super(n),this.name="AuthJsonValidationError",this.code=e;}},i=class extends s{constructor(e){let n=e.startsWith("ACCOUNT_BASE_URL")?"CREWX_ACCOUNT_BASE_URL":e.startsWith("ACCOUNT_ISSUER")?"CREWX_ACCOUNT_ISSUER":e==="ACCOUNT_TARGET_INVALID"?"CREWX_TARGET":e==="ACCOUNT_TARGET_MIXED"?"CREWX_ACCOUNT_BASE_URL/CREWX_MARKETPLACE_URL":e==="MARKETPLACE_DISABLED"?"CREWX_MARKETPLACE_DISABLED":"CREWX_MARKETPLACE_URL",r=e==="ACCOUNT_TARGET_MIXED"?`${n} must not mix loopback and public hosts \u2014 choose one account target`:e==="MARKETPLACE_DISABLED"?`${n} disables Marketplace access`:`${n} is missing or invalid \u2014 configure it and try again`;super(e,"configuration",void 0,r),this.name="AccountConfigurationError";}};var O="CREWX_ACCOUNT_BASE_URL",I="CREWX_ACCOUNT_ISSUER",x="CREWX_MARKETPLACE_URL",L="CREWX_TARGET",X="CREWX_MARKETPLACE_DISABLED",R=Object.freeze({accountBaseUrl:"https://app.sowonai.com",marketplaceUrl:"https://market.sowonai.com"}),k=Object.freeze({accountBaseUrl:"http://127.0.0.1:3030",marketplaceUrl:"http://127.0.0.1:4000"}),D=Object.freeze(["https://app.sowonai.com/auth/v1","https://auth.sowonai.com/auth/v1"]);function P(t,e,n=false){let r=t?.trim();if(!r)throw new i(e);try{let o=new URL(r);if(o.protocol!=="http:"&&o.protocol!=="https:"||o.username.length>0||o.password.length>0||o.hostname.length===0||o.search.length>0||o.hash.length>0||n&&o.pathname!=="/")throw new Error("invalid URL")}catch{throw new i(e)}return r.replace(/\/+$/,"")}function q(t){let e=t?.trim();if(!e)throw new i("ACCOUNT_ISSUER_INVALID");try{let n=new URL(e);if(n.protocol!=="http:"&&n.protocol!=="https:"||n.username.length>0||n.password.length>0||n.hostname.length===0||n.search.length>0||n.hash.length>0)throw new Error("invalid issuer")}catch{throw new i("ACCOUNT_ISSUER_INVALID")}return e}function b(t){let e=t[L];if(e===void 0)return "production";let n=e.trim();if(n==="local"||n==="production")return n;throw new i("ACCOUNT_TARGET_INVALID")}function F(t){let e=t[X]?.trim().toLowerCase();return e==="1"||e==="true"}function V(t){return t==="local"?k:R}function J(t=process.env){let e=b(t),n=t[O];return n!==void 0?P(n,"ACCOUNT_BASE_URL_INVALID",true):V(e).accountBaseUrl}function de(t=process.env){let e=b(t);if(F(t))throw new i("MARKETPLACE_DISABLED");let n=t[x];return n!==void 0?P(n,"MARKETPLACE_URL_INVALID"):V(e).marketplaceUrl}function U(t=process.env){let e=t[I];return e===void 0?D:[q(e)]}function Ae(t=process.env){return U(t)[0]}function W(t,e,n,r=false){if(t===void 0)return e;try{return P(t,n,r)}catch{return t.trim()}}function _e(t){let e=t[I];if(e===void 0)return D;try{return [q(e)]}catch{return [e.trim()]}}function j(t){if(t===null)return false;try{let e=new URL(t).hostname.toLowerCase();return e==="127.0.0.1"||e==="localhost"||e==="[::1]"||e==="::1"}catch{return false}}function ge(t,e){return e!==null&&t===R.accountBaseUrl&&e===R.marketplaceUrl?"production":e!==null&&t===k.accountBaseUrl&&e===k.marketplaceUrl?"local":"custom"}function $(t=process.env){let e,n=true;try{e=b(t);}catch{e="production",n=false;}let r=V(e),o=t[L]!==void 0&&n,c=t[O],T=t[x],u=F(t),d=W(c,r.accountBaseUrl,"ACCOUNT_BASE_URL_INVALID",true),y=u?null:W(T,r.marketplaceUrl,"MARKETPLACE_URL_INVALID");return {accountBaseUrl:d,marketplaceUrl:y,issuers:_e(t),profile:ge(d,y),sources:{accountBaseUrl:c===void 0?o?"profile":"default":"env",marketplaceUrl:u?"disabled":T===void 0?o?"profile":"default":"env",issuer:t[I]===void 0?"default":"env"},mixed:y!==null&&j(d)!==j(y),marketplaceDisabled:u}}function Ee(t=process.env){if($(t).mixed)throw new i("ACCOUNT_TARGET_MIXED")}function M(t,e){return `${t.replace(/\/+$/,"")}/${e.replace(/^\/+/,"")}`}function v(){if(process.env.CREWX_HOME){let t=C.resolve(process.env.CREWX_HOME);try{return Y.realpathSync(t)}catch(e){if(e instanceof Error&&"code"in e&&e.code==="ENOENT")return t;throw e}}return process.platform!=="win32"&&process.env.XDG_CONFIG_HOME?C.join(process.env.XDG_CONFIG_HOME,"crewx"):C.join(z.homedir(),".crewx")}var te="CREWX_TASK_TICKET_SECRET";function ne(t={}){let e=t.workspaceDir??process.env.CREWX_WORKSPACE??process.cwd(),n=t.homeDir??v();return {workspace:join(e,".env"),home:join(n,".env")}}function me(t){try{return new Set(Object.keys(parse(readFileSync(t))))}catch(e){if(e?.code==="ENOENT")return new Set;throw e}}function Te(t){try{return parse(readFileSync(t))}catch(e){if(e?.code==="ENOENT")return {};throw e}}function Ce(t={}){let e=ne(t);for(let n of [e.workspace,e.home]){let r=Te(n);for(let[o,c]of Object.entries(r))o===te||process.env[o]!==void 0||(process.env[o]=c);}}var ie="auth.json",H=2,se=["version","sub","email","access_token","refresh_token","expires_at","updated_at"];function h(t="auth.json is invalid \u2014 please log in again"){throw new p("AUTH_JSON_INVALID",t)}function ve(){throw new p("AUTH_JSON_LEGACY","auth.json uses an unsupported legacy format \u2014 please log in again")}function Ne(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Oe(t){try{return E(t),!0}catch{return false}}function E(t){if(!Ne(t))return h();if(t.version===1)return ve();if(t.version!==H)return h();let e=Object.keys(t);if(e.length!==se.length||e.some(r=>!se.includes(r))||typeof t.sub!="string"||t.sub.length===0||typeof t.email!="string"||t.email.length===0||typeof t.access_token!="string"||t.access_token.length===0||typeof t.refresh_token!="string"||t.refresh_token.length===0)return h();let n=t.expires_at;return typeof n!="number"||!Number.isSafeInteger(n)||n<0||typeof t.updated_at!="string"||t.updated_at.length===0||Number.isNaN(Date.parse(t.updated_at))?h():{version:H,sub:t.sub,email:t.email,access_token:t.access_token,refresh_token:t.refresh_token,expires_at:n,updated_at:t.updated_at}}function ce(t){let e;try{e=JSON.parse(t);}catch{return h()}return E(e)}function ae(t){return t??join(v(),ie)}var A=class{configuredPath;constructor(e={}){this.configuredPath=typeof e=="string"?e:e.filePath;}path(){return ae(this.configuredPath)}read(){let e=this.path();if(!existsSync(e))return null;try{return ce(readFileSync(e,"utf8"))}catch(n){throw n instanceof p?n:new p("AUTH_JSON_INVALID")}}write(e){let n=E(e),r=this.path(),o=dirname(r);mkdirSync(o,{recursive:true,mode:448});let c=`${r}.tmp.${process.pid}.${randomUUID()}`;try{writeFileSync(c,JSON.stringify(n,null,2),{encoding:"utf8",mode:384}),chmodSync(c,384),renameSync(c,r),chmodSync(r,384);}catch{try{existsSync(c)&&unlinkSync(c);}catch{}throw new Error("Could not persist auth.json securely")}}clear(){let e=this.path();try{existsSync(e)&&unlinkSync(e);}catch{throw new Error("Could not clear auth.json")}}};function xe(t){let e=new A({filePath:t}).read();if(!e)throw new l;return e}function Le(t,e){new A({filePath:e}).write(t);}function De(t){new A({filePath:t}).clear();}var pe="/auth/v1/oauth/device/code",he="/auth/v1/oauth/token",le="/auth/v1/oauth/revoke",N="crewx-cli",m="urn:ietf:params:oauth:grant-type:device_code";function a(t){return typeof t=="string"&&t.trim().length>0}function w(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)?t:null}function Pe(t){let e=w(t),n=e?.error??e?.code;if(typeof n=="string")return n.toLowerCase();let r=w(n),o=r?.code??r?.error;return typeof o=="string"?o.toLowerCase():void 0}function be(t){let e=w(t);if(!e||!a(e.device_code)||!a(e.user_code)||!a(e.verification_uri))throw new s("AUTH_RESPONSE_INVALID","protocol");let n=e.expires_in,r=e.interval;if(typeof n!="number"||!Number.isSafeInteger(n)||n<=0)throw new s("AUTH_RESPONSE_INVALID","protocol");if(e.verification_uri_complete!==void 0&&!a(e.verification_uri_complete))throw new s("AUTH_RESPONSE_INVALID","protocol");if(r!==void 0&&(typeof r!="number"||!Number.isSafeInteger(r)||r<0))throw new s("AUTH_RESPONSE_INVALID","protocol");let o={device_code:e.device_code,user_code:e.user_code,verification_uri:e.verification_uri,expires_in:n};return e.verification_uri_complete!==void 0&&(o.verification_uri_complete=e.verification_uri_complete),r!==void 0&&(o.interval=r),o}function Ve(t){let e=w(t),n=w(e?.account),r=e?.expires_in;if(!e||!a(e.access_token)||!a(e.refresh_token)||typeof r!="number"||!Number.isSafeInteger(r)||r<=0||!n||!a(n.sub)||!a(n.email))throw new s("AUTH_RESPONSE_INVALID","protocol");let o={access_token:e.access_token,refresh_token:e.refresh_token,expires_in:r,account:{sub:n.sub,email:n.email}};return typeof e.token_type=="string"&&e.token_type.length>0&&(o.token_type=e.token_type),typeof e.scope=="string"&&e.scope.length>0&&(o.scope=e.scope),o}var S=class{configuredBaseUrl;fetchImpl;timeoutMs;constructor(e={}){let n=typeof e=="string"?{baseUrl:e}:e;this.configuredBaseUrl=n.baseUrl===void 0?void 0:Je(n.baseUrl),this.fetchImpl=n.fetch??n.fetchImpl,this.timeoutMs=n.timeoutMs??1e4;}baseUrl(){return this.configuredBaseUrl!==void 0?this.configuredBaseUrl:J()}signal(e){if(!(e<=0||typeof AbortSignal>"u"||typeof AbortSignal.timeout!="function"))return AbortSignal.timeout(e)}async request(e,n,r,o={}){let c=M(this.baseUrl(),e),T=this.fetchImpl??globalThis.fetch;if(typeof T!="function")throw new s("AUTH_NETWORK_ERROR","network");let u;try{u=await T(c,{...n,signal:n.signal??this.signal(o.timeoutMs??this.timeoutMs)});}catch{throw new s("AUTH_NETWORK_ERROR","network")}if(o.parseBody===false){if(!u.ok)throw ue(u.status,null,r);return}let d=null;try{d=await u.json();}catch{d=null;}if(!u.ok)throw ue(u.status,d,r);return d}async requestDeviceCode(){let e=new URLSearchParams;e.set("client_id",N);let n=await this.request(pe,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:e.toString()});return be(n)}async requestToken(e){Me(e);let n=new URLSearchParams;n.set("grant_type",e.grant_type),n.set("client_id",N),e.grant_type===m?n.set("device_code",e.device_code):n.set("refresh_token",e.refresh_token);let r=await this.request(he,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:n.toString()},e);return Ve(r)}async exchangeDeviceCode(e){return this.requestToken({grant_type:m,device_code:e})}async refreshToken(e){return this.requestToken({grant_type:"refresh_token",refresh_token:e})}async deviceCode(){return this.requestDeviceCode()}async getDeviceCode(){return this.requestDeviceCode()}async token(e){return this.requestToken(e)}async getToken(e){return this.requestToken(e)}async refresh(e){return this.refreshToken(e)}async refreshAccessToken(e){return this.refreshToken(e)}async revokeToken(e){if(!a(e))throw new s("AUTH_INPUT_INVALID","protocol");let n=new URLSearchParams;n.set("token",e),n.set("token_type_hint","refresh_token"),n.set("client_id",N),await this.request(le,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:n.toString()},void 0,{parseBody:false,timeoutMs:3e3});}async revoke(e){return this.revokeToken(e)}};function Je(t){if(typeof t!="string"||!t.trim())throw new i("ACCOUNT_BASE_URL_INVALID");try{let e=new URL(t.trim());if(e.protocol!=="http:"&&e.protocol!=="https:"||e.username.length>0||e.password.length>0||e.hostname.length===0||e.pathname!=="/"||e.search.length>0||e.hash.length>0)throw new Error("invalid URL")}catch{throw new i("ACCOUNT_BASE_URL_INVALID")}return t.trim().replace(/\/+$/,"")}function Me(t){if(!t||t.grant_type!==m&&t.grant_type!=="refresh_token"||t.grant_type===m&&!a(t.device_code)||t.grant_type==="refresh_token"&&!a(t.refresh_token))throw new s("AUTH_INPUT_INVALID","protocol")}function ue(t,e,n){let r=Pe(e);if(t>=500)return new s("AUTH_SERVER_ERROR","server",t);if(n?.grant_type==="refresh_token"&&(r==="invalid_grant"||t===401))return new s("INVALID_REFRESH_TOKEN","invalid_refresh",t);if(n?.grant_type===m){if(r==="authorization_pending")return new s("AUTHORIZATION_PENDING","pending",t);if(r==="slow_down")return new s("SLOW_DOWN","pending",t);if(r==="access_denied")return new s("ACCESS_DENIED","denied",t);if(r==="expired_token")return new s("EXPIRED_TOKEN","expired",t)}return new s("AUTH_HTTP_ERROR","http",t)}var G=class{client;store;refreshSkewSeconds;now;nowSecondsOverride;refreshPromise=null;constructor(e={},n){let r=He(e)?e:void 0,o=r?{}:e;this.client=r??o.client??o.authClient??new S,this.store=o.store??o.storage??n??new A,this.refreshSkewSeconds=o.refreshSkewSeconds??60,this.now=o.now??(()=>Date.now()),this.nowSecondsOverride=o.nowSeconds;}getSession(){return this.readSession()}isLoggedIn(){return this.readSession()!==null}async getAccessToken(){let e=this.requireSession();return e.expires_at>this.epochSeconds()+this.refreshSkewSeconds?e.access_token:(await this.refreshSession(e)).access_token}async getValidAccessToken(){return this.getAccessToken()}async getToken(){return this.getAccessToken()}async refresh(){return this.refreshSession(this.requireSession())}async loginWithDeviceCode(e){let n=await this.client.exchangeDeviceCode(e);return this.persistTokenResponse(n)}async login(e){return this.loginWithDeviceCode(e)}async setSession(e){return this.persistTokenResponse(e)}clear(){this.store.clear();}async withAccessToken(e){return e(await this.getAccessToken())}readSession(){try{let e=this.store.read();if(e===null)return null;let n=E(e);return fe(n.access_token,n.sub),n}catch(e){throw e instanceof p?new l:e}}requireSession(){let e=this.readSession();if(!e)throw new l;return e}epochSeconds(){return this.nowSecondsOverride?.()??Math.floor(this.now()/1e3)}refreshSession(e){if(this.refreshPromise)return this.refreshPromise;let n;return n=this.performRefresh(e).finally(()=>{this.refreshPromise===n&&(this.refreshPromise=null);}),this.refreshPromise=n,n}async performRefresh(e){try{let n=await this.client.refreshToken(e.refresh_token);return this.persistTokenResponse(n,e.sub)}catch(n){throw Be(n)?(this.store.clear(),new l):n}}persistTokenResponse(e,n){let r=e?.account;if(!e||typeof e.access_token!="string"||e.access_token.length===0||typeof e.refresh_token!="string"||e.refresh_token.length===0||!Number.isSafeInteger(e.expires_in)||e.expires_in<=0||!r||typeof r.sub!="string"||r.sub.length===0||typeof r.email!="string"||r.email.length===0)throw new f("AUTH_RESPONSE_INVALID","Account token response is malformed");if(n!==void 0&&r.sub!==n)throw new f("ACCOUNT_SUB_MISMATCH","Account subject changed during token refresh \u2014 please log in again");fe(e.access_token,r.sub);let o=E({version:2,sub:r.sub,email:r.email,access_token:e.access_token,refresh_token:e.refresh_token,expires_at:this.epochSeconds()+e.expires_in,updated_at:new Date(this.now()).toISOString()});return this.store.write(o),o}};function Be(t){return t instanceof s?t.kind==="invalid_refresh":typeof t=="object"&&t!==null&&(t.kind==="invalid_refresh"||t.code==="INVALID_REFRESH_TOKEN")}function He(t){return typeof t.exchangeDeviceCode=="function"&&typeof t.refreshToken=="function"}function fe(t,e){let n=U(),r=Ke(t);if(!n.includes(r.iss))throw new f("ACCOUNT_ISSUER_MISMATCH","Access token issuer does not match the configured account issuer \u2014 please log in again");if(r.sub!==e)throw new f("ACCOUNT_SUB_MISMATCH","Access token subject does not match the account session \u2014 please log in again")}function Ke(t){if(typeof t!="string")throw K();let e=t.split(".");if(e.length!==3||e.some(n=>!/^[A-Za-z0-9_-]+$/.test(n)))throw K();try{let n=JSON.parse(Buffer.from(e[1],"base64url").toString("utf8"));if(typeof n!="object"||n===null||Array.isArray(n)||typeof n.iss!="string"||n.iss.length===0||typeof n.sub!="string"||n.sub.length===0)throw new Error("missing identity claims");return {iss:n.iss,sub:n.sub}}catch{throw K()}}function K(){return new f("ACCESS_TOKEN_INVALID","Access token identity could not be verified \u2014 please log in again")}
|
|
2
|
+
export{O as ACCOUNT_BASE_URL_ENV,I as ACCOUNT_ISSUER_ENV,L as ACCOUNT_TARGET_ENV,ie as AUTH_JSON_FILENAME,H as AUTH_JSON_VERSION,s as AccountAuthError,i as AccountConfigurationError,S as AuthClient,s as AuthClientError,s as AuthError,A as AuthJsonStore,p as AuthJsonValidationError,te as CREWX_TASK_TICKET_SECRET_ENV,D as DEFAULT_ACCEPTED_ISSUERS,m as DEVICE_CODE_GRANT_TYPE,pe as DEVICE_CODE_PATH,k as LOCAL_TARGET,l as LoginRequiredError,X as MARKETPLACE_DISABLED_ENV,x as MARKETPLACE_URL_ENV,N as OAUTH_CLIENT_ID,R as PRODUCTION_TARGET,le as REVOKE_PATH,G as SessionManager,f as SessionManagerError,he as TOKEN_PATH,M as appendEndpoint,Ee as assertAccountTargetNotMixed,ae as authJsonPath,De as clearAuthJson,Oe as isAuthJsonV2,Ce as loadCrewxEnvFiles,ce as parseAuthJson,xe as readAuthJson,me as readCrewxEnvFileKeys,U as resolveAcceptedAccountIssuers,J as resolveAccountBaseUrl,Ae as resolveAccountIssuer,$ as resolveAccountTarget,ne as resolveCrewxEnvFilePaths,de as resolveMarketplaceUrl,E as validateAuthJson,Le as writeAuthJson};
|