@wix/himalaya-cli 0.1458.0 → 0.1459.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export declare const WIX_API = "https://www.wixapis.com";
|
|
1
2
|
/** The narrow Wix consumer endpoints allowed to receive credentials for SSE. */
|
|
2
3
|
export declare function isAllowedConsumerStreamTarget(raw: string): boolean;
|
|
3
4
|
/** Classify an absolute-URL rejection: an off-gateway Wix account host is a
|
package/dist/cli.mjs
CHANGED
|
@@ -1059,8 +1059,8 @@ function toBase64(bytes2) {
|
|
|
1059
1059
|
function utf8Decode(bytes2) {
|
|
1060
1060
|
return new TextDecoder("utf-8").decode(bytes2);
|
|
1061
1061
|
}
|
|
1062
|
-
function fromBase64Url(
|
|
1063
|
-
const std =
|
|
1062
|
+
function fromBase64Url(b64url4) {
|
|
1063
|
+
const std = b64url4.replace(/-/g, "+").replace(/_/g, "/");
|
|
1064
1064
|
return fromBase64(std + "=".repeat((4 - std.length % 4) % 4));
|
|
1065
1065
|
}
|
|
1066
1066
|
function toBase64Url(bytes2) {
|
|
@@ -160096,6 +160096,122 @@ var init_pinned_read = __esm({
|
|
|
160096
160096
|
}
|
|
160097
160097
|
});
|
|
160098
160098
|
|
|
160099
|
+
// ../../core/serve-runtime/src/member-exchange.ts
|
|
160100
|
+
function hopAllowed(url, firstHost) {
|
|
160101
|
+
if (url.protocol !== "https:" || url.port !== "" && url.port !== "443" || url.username || url.password) return false;
|
|
160102
|
+
const host = url.hostname.toLowerCase();
|
|
160103
|
+
return host === firstHost || host === "wix.com" || host.endsWith(".wix.com") || host.endsWith(".wixsite.com") || host === "wixapis.com" || host.endsWith(".wixapis.com");
|
|
160104
|
+
}
|
|
160105
|
+
async function exchangeMemberSession(input, fetchImpl = fetch, random = randomBytes6, now = Date.now, redirectUri = REGISTERED_REDIRECT_URI) {
|
|
160106
|
+
const { clientId, sessionToken } = input;
|
|
160107
|
+
if (typeof sessionToken !== "string" || !sessionToken || sessionToken.length > MAX_SESSION_TOKEN_LENGTH) {
|
|
160108
|
+
return { ok: false, code: "bad_request" };
|
|
160109
|
+
}
|
|
160110
|
+
const call = async (url2, init) => {
|
|
160111
|
+
try {
|
|
160112
|
+
return await fetchImpl(url2, { ...init, signal: AbortSignal.timeout(STEP_TIMEOUT_MS) });
|
|
160113
|
+
} catch {
|
|
160114
|
+
return null;
|
|
160115
|
+
}
|
|
160116
|
+
};
|
|
160117
|
+
const json8 = async (res) => {
|
|
160118
|
+
try {
|
|
160119
|
+
const v2 = await res.json();
|
|
160120
|
+
return v2 && typeof v2 === "object" ? v2 : {};
|
|
160121
|
+
} catch {
|
|
160122
|
+
return {};
|
|
160123
|
+
}
|
|
160124
|
+
};
|
|
160125
|
+
let visitor;
|
|
160126
|
+
try {
|
|
160127
|
+
visitor = await mintAnonymousVisitor(clientId, (u2, i2) => call(String(u2), i2 ?? {}).then((r2) => {
|
|
160128
|
+
if (!r2) throw new Error("unreachable");
|
|
160129
|
+
return r2;
|
|
160130
|
+
}));
|
|
160131
|
+
} catch (e2) {
|
|
160132
|
+
return { ok: false, code: e2?.message === "unreachable" ? "unreachable" : "visitor_token_failed" };
|
|
160133
|
+
}
|
|
160134
|
+
const verifier = b64url2(random(32));
|
|
160135
|
+
const challenge = b64url2(sha256(verifier));
|
|
160136
|
+
const state = b64url2(random(8));
|
|
160137
|
+
const rsRes = await call(`${WIX_API}/_api/redirects-api/v1/redirect-session`, {
|
|
160138
|
+
method: "POST",
|
|
160139
|
+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${visitor}` },
|
|
160140
|
+
body: JSON.stringify({ auth: { authRequest: {
|
|
160141
|
+
clientId,
|
|
160142
|
+
responseType: "code",
|
|
160143
|
+
responseMode: "fragment",
|
|
160144
|
+
redirectUri,
|
|
160145
|
+
scope: "offline_access",
|
|
160146
|
+
state,
|
|
160147
|
+
nonce: state,
|
|
160148
|
+
codeChallenge: challenge,
|
|
160149
|
+
codeChallengeMethod: "S256",
|
|
160150
|
+
sessionToken
|
|
160151
|
+
}, prompt: "none" } })
|
|
160152
|
+
});
|
|
160153
|
+
if (!rsRes) return { ok: false, code: "unreachable" };
|
|
160154
|
+
const rs2 = await json8(rsRes);
|
|
160155
|
+
const fullUrl = rs2.redirectSession?.fullUrl;
|
|
160156
|
+
if (!rsRes.ok || typeof fullUrl !== "string") return { ok: false, code: "redirect_session_failed", status: rsRes.status };
|
|
160157
|
+
let url;
|
|
160158
|
+
try {
|
|
160159
|
+
url = new URL(fullUrl);
|
|
160160
|
+
} catch {
|
|
160161
|
+
return { ok: false, code: "redirect_session_failed", status: rsRes.status };
|
|
160162
|
+
}
|
|
160163
|
+
const firstHost = url.hostname.toLowerCase();
|
|
160164
|
+
let code;
|
|
160165
|
+
let lastStatus;
|
|
160166
|
+
for (let hop = 0; hop < MAX_HOPS; hop++) {
|
|
160167
|
+
if (!hopAllowed(url, firstHost)) return { ok: false, code: "authorize_host_refused" };
|
|
160168
|
+
const res = await call(url.toString(), { method: "GET", redirect: "manual", headers: { "User-Agent": "Mozilla/5.0" } });
|
|
160169
|
+
if (!res) return { ok: false, code: "unreachable" };
|
|
160170
|
+
lastStatus = res.status;
|
|
160171
|
+
const location = res.headers.get("location");
|
|
160172
|
+
if (!location) return { ok: false, code: res.status >= 400 ? "authorize_refused" : "authorize_no_code", status: res.status };
|
|
160173
|
+
if (location.startsWith(redirectUri)) {
|
|
160174
|
+
const params = new URLSearchParams(location.slice(redirectUri.length).replace(/^[?#]/, ""));
|
|
160175
|
+
if (params.get("state") !== state) return { ok: false, code: "authorize_state_mismatch" };
|
|
160176
|
+
code = params.get("code") ?? void 0;
|
|
160177
|
+
break;
|
|
160178
|
+
}
|
|
160179
|
+
try {
|
|
160180
|
+
url = new URL(location, url);
|
|
160181
|
+
} catch {
|
|
160182
|
+
return { ok: false, code: "authorize_no_code", status: res.status };
|
|
160183
|
+
}
|
|
160184
|
+
}
|
|
160185
|
+
if (!code) return { ok: false, code: "authorize_no_code", ...lastStatus !== void 0 ? { status: lastStatus } : {} };
|
|
160186
|
+
const tokRes = await call(`${WIX_API}/oauth2/token`, {
|
|
160187
|
+
method: "POST",
|
|
160188
|
+
headers: { "Content-Type": "application/json" },
|
|
160189
|
+
body: JSON.stringify({ clientId, grantType: "authorization_code", code, codeVerifier: verifier, redirectUri })
|
|
160190
|
+
});
|
|
160191
|
+
if (!tokRes) return { ok: false, code: "unreachable" };
|
|
160192
|
+
const tok = await json8(tokRes);
|
|
160193
|
+
if (!tokRes.ok || typeof tok.access_token !== "string" || !tok.access_token) return { ok: false, code: "token_exchange_failed", status: tokRes.status };
|
|
160194
|
+
const expiresIn = typeof tok.expires_in === "number" ? tok.expires_in : Number(tok.expires_in);
|
|
160195
|
+
return { ok: true, accessToken: tok.access_token, expiresAt: now() + (Number.isFinite(expiresIn) && expiresIn > 0 ? expiresIn : 3600) * 1e3 };
|
|
160196
|
+
}
|
|
160197
|
+
var REGISTERED_REDIRECT_URI, MAX_HOPS, STEP_TIMEOUT_MS, MAX_SESSION_TOKEN_LENGTH, b64url2, randomBytes6;
|
|
160198
|
+
var init_member_exchange = __esm({
|
|
160199
|
+
"../../core/serve-runtime/src/member-exchange.ts"() {
|
|
160200
|
+
init_sha256();
|
|
160201
|
+
init_wix_bridge();
|
|
160202
|
+
REGISTERED_REDIRECT_URI = "himalaya-appsmith://oauth/callback";
|
|
160203
|
+
MAX_HOPS = 8;
|
|
160204
|
+
STEP_TIMEOUT_MS = 8e3;
|
|
160205
|
+
MAX_SESSION_TOKEN_LENGTH = 4096;
|
|
160206
|
+
b64url2 = (bytes2) => {
|
|
160207
|
+
let s2 = "";
|
|
160208
|
+
for (const b2 of bytes2) s2 += String.fromCharCode(b2);
|
|
160209
|
+
return btoa(s2).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
160210
|
+
};
|
|
160211
|
+
randomBytes6 = (n2) => globalThis.crypto.getRandomValues(new Uint8Array(n2));
|
|
160212
|
+
}
|
|
160213
|
+
});
|
|
160214
|
+
|
|
160099
160215
|
// ../../core/serve-runtime/package-share.ts
|
|
160100
160216
|
function parseStored(bytes2, id) {
|
|
160101
160217
|
if (!bytes2) return null;
|
|
@@ -160930,6 +161046,32 @@ ${releaseId}`;
|
|
|
160930
161046
|
}
|
|
160931
161047
|
return new Response(upstream.body, { status: upstream.status, headers: responseHeaders });
|
|
160932
161048
|
}
|
|
161049
|
+
if (request.method === "POST" && path2 === "/v1/__webwix/member-exchange") {
|
|
161050
|
+
const noStore = { "cache-control": "no-store" };
|
|
161051
|
+
if (opts.webwixBridge === false) return json5(503, { error: "webwix_bridge_disabled" }, noStore);
|
|
161052
|
+
if (!opts.previewTokenSecret) return json5(503, { error: "preview_token_unavailable" }, noStore);
|
|
161053
|
+
const exchangeApp = resolveApp(request, url);
|
|
161054
|
+
if (!exchangeApp) return json5(400, { error: "app_required" }, noStore);
|
|
161055
|
+
const exchangePin = resolvePin(request, url);
|
|
161056
|
+
if (!exchangePin || !resolvePreviewToken(request, url)) return json5(403, { error: "draft_preview_required" }, noStore);
|
|
161057
|
+
const exchangeCfg = await appConfigFor(request, url, exchangeApp);
|
|
161058
|
+
if (!exchangeCfg.ok) return exchangeCfg.response;
|
|
161059
|
+
if ((await manifest(exchangeApp))?.releaseId === exchangePin || await isRingRelease(exchangeApp, exchangePin)) {
|
|
161060
|
+
return json5(403, { error: "draft_preview_required" }, noStore);
|
|
161061
|
+
}
|
|
161062
|
+
const exchangeClient = wixClientIdOf(utf8Decode(exchangeCfg.bytes));
|
|
161063
|
+
if ("error" in exchangeClient) return json5(501, { error: `member_exchange_${exchangeClient.error}` }, noStore);
|
|
161064
|
+
let exchangeBody;
|
|
161065
|
+
try {
|
|
161066
|
+
exchangeBody = await request.json();
|
|
161067
|
+
} catch {
|
|
161068
|
+
return json5(400, { error: "bad_request" }, noStore);
|
|
161069
|
+
}
|
|
161070
|
+
if (!exchangeBody || typeof exchangeBody !== "object") return json5(400, { error: "bad_request" }, noStore);
|
|
161071
|
+
const exchanged = await exchangeMemberSession({ clientId: exchangeClient.clientId, sessionToken: exchangeBody.sessionToken }, webwixFetch);
|
|
161072
|
+
if (exchanged.ok) return json5(200, { accessToken: exchanged.accessToken, expiresAt: exchanged.expiresAt }, noStore);
|
|
161073
|
+
return json5(exchanged.code === "bad_request" ? 400 : 502, { error: exchanged.code, ...exchanged.status !== void 0 ? { status: exchanged.status } : {} }, noStore);
|
|
161074
|
+
}
|
|
160933
161075
|
if (request.method === "POST" && path2 === "/v1/__webwix/call") {
|
|
160934
161076
|
const served = { rung: "none" };
|
|
160935
161077
|
let status = 500;
|
|
@@ -161546,6 +161688,7 @@ var init_server2 = __esm({
|
|
|
161546
161688
|
init_base64();
|
|
161547
161689
|
init_contract();
|
|
161548
161690
|
init_pinned_read();
|
|
161691
|
+
init_member_exchange();
|
|
161549
161692
|
init_package_share();
|
|
161550
161693
|
init_wix_bridge();
|
|
161551
161694
|
init_account_rung();
|
|
@@ -162598,14 +162741,14 @@ var init_embedded_bundles = __esm({
|
|
|
162598
162741
|
// ../store-release/register-bundle.ts
|
|
162599
162742
|
import { readFileSync as readFileSync88 } from "node:fs";
|
|
162600
162743
|
import { createPrivateKey as createPrivateKey4, sign as sign2 } from "node:crypto";
|
|
162601
|
-
function
|
|
162744
|
+
function b64url3(b2) {
|
|
162602
162745
|
return Buffer.from(b2).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
162603
162746
|
}
|
|
162604
162747
|
function ascJwt(keyId, issuerId, p8, now) {
|
|
162605
|
-
const header =
|
|
162606
|
-
const payload =
|
|
162748
|
+
const header = b64url3(JSON.stringify({ alg: "ES256", kid: keyId, typ: "JWT" }));
|
|
162749
|
+
const payload = b64url3(JSON.stringify({ iss: issuerId, iat: now, exp: now + 1200, aud: "appstoreconnect-v1" }));
|
|
162607
162750
|
const key3 = createPrivateKey4(p8);
|
|
162608
|
-
const sig =
|
|
162751
|
+
const sig = b64url3(sign2("sha256", Buffer.from(`${header}.${payload}`), { key: key3, dsaEncoding: "ieee-p1363" }));
|
|
162609
162752
|
return `${header}.${payload}.${sig}`;
|
|
162610
162753
|
}
|
|
162611
162754
|
function bundleIdBody(identifier, name, platform = "IOS") {
|
|
@@ -167782,7 +167925,7 @@ var init_connector_token = __esm({
|
|
|
167782
167925
|
});
|
|
167783
167926
|
|
|
167784
167927
|
// ../../core/functions-secrets/src/vault.ts
|
|
167785
|
-
import { createCipheriv, createDecipheriv as createDecipheriv2, randomBytes as
|
|
167928
|
+
import { createCipheriv, createDecipheriv as createDecipheriv2, randomBytes as randomBytes7 } from "node:crypto";
|
|
167786
167929
|
import { mkdir, readFile as readFile2, rename, writeFile as writeFile2 } from "node:fs/promises";
|
|
167787
167930
|
import { dirname as dirname44 } from "node:path";
|
|
167788
167931
|
function createJsonSecretStore(filePath) {
|
|
@@ -167840,7 +167983,7 @@ function createSecretVault(options) {
|
|
|
167840
167983
|
environment: input.environment,
|
|
167841
167984
|
name: input.name,
|
|
167842
167985
|
version: input.version,
|
|
167843
|
-
iv:
|
|
167986
|
+
iv: randomBytes7(12).toString("base64url"),
|
|
167844
167987
|
ciphertext: "",
|
|
167845
167988
|
authTag: ""
|
|
167846
167989
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1459.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "himi — the Himalaya authoring CLI. Build a Tier-5 content package on your own machine, push it to the production serve as a draft, preview it on web + Himi Player, and read worker logs back — the remote dev loop. Wraps @himalaya/serve-cli for transport.",
|
|
6
6
|
"keywords": [
|
|
@@ -71,5 +71,5 @@
|
|
|
71
71
|
"artifactId": "himalaya-cli"
|
|
72
72
|
}
|
|
73
73
|
},
|
|
74
|
-
"falconPackageHash": "
|
|
74
|
+
"falconPackageHash": "db96f8e1d9f3f0a55120ae97f89b4211fed249d7a3f98225dc9269b1"
|
|
75
75
|
}
|