@wix/himalaya-cli 0.1469.0 → 0.1471.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.
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/dev-server/src/app-config.d.ts +10 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/wix-platform/src/index.d.ts +13 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/auth-gate-screen.d.ts +10 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/define-app.d.ts +16 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/core.mjs +15 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-platform.mjs +29 -8
- package/dist/cli.mjs +58 -31
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/hhp.md +4 -4
- package/guides/sdk-reference.json +2 -2
- package/guides/web-page-sdk-reference.md +1 -1
- package/guides/wix-login-integration.md +56 -4
- package/guides/wix-platform-usage.md +26 -11
- package/package.json +2 -2
|
@@ -2,6 +2,7 @@ import type { IncomingMessage, ServerResponse } from "node:http";
|
|
|
2
2
|
import type { DerivedAppMeta } from "./app-module.js";
|
|
3
3
|
import { type WixCachePolicy } from "./wix-cache-policy.js";
|
|
4
4
|
import type { NetMocksFile, WixMockRule } from "./wix-gateway.js";
|
|
5
|
+
import { gateScreenIdProblem } from "../../ts/src/auth-gate-screen.js";
|
|
5
6
|
import { type UnmappedPushDestination } from "../../ts/src/wix-push-links.js";
|
|
6
7
|
import type { PushConfig, FlagConfig, AppControl, TabBarConfig, DrawerConfig, SidebarConfig, SplashConfig, LocaleConfig, NavKind, OrientationConfig, StreamPolicy } from "@wix/himalaya/core";
|
|
7
8
|
export type { PushConfig, FlagConfig, AppControl, TabBarConfig, DrawerConfig, SidebarConfig, SplashConfig, LocaleConfig, NavKind, OrientationConfig, StreamPolicy };
|
|
@@ -37,6 +38,7 @@ export interface TelemetryConfig {
|
|
|
37
38
|
export interface AuthConfigBlock {
|
|
38
39
|
providerId: string;
|
|
39
40
|
required: boolean;
|
|
41
|
+
gateScreenId?: string;
|
|
40
42
|
config: Record<string, unknown>;
|
|
41
43
|
}
|
|
42
44
|
/** RFC 0010 (nav-modes amendment) — OTA back-affordance config. `enabled` gates
|
|
@@ -195,13 +197,19 @@ export interface DevGatewayConfig {
|
|
|
195
197
|
* answers a miss with the same 404 and never calls the real capability. */
|
|
196
198
|
unmatched?: "passthrough" | "fail";
|
|
197
199
|
}
|
|
200
|
+
/** #4651 — the gate-screen existence rule lives import-free in core (the auth bake shares it). */
|
|
201
|
+
export { gateScreenIdProblem };
|
|
198
202
|
/** Derive the OTA authConfig block from a defineApp auth block
|
|
199
203
|
* ({ providerId, config }). `required` is read from `config.required === true`
|
|
200
|
-
* and lifted to the top level; secret-ish
|
|
204
|
+
* and lifted to the top level, as is `config.gateScreenId` (#4651); secret-ish
|
|
205
|
+
* keys are scrubbed. When the app's screens are given, a `gateScreenId` naming none
|
|
206
|
+
* of them is DROPPED (the shell falls back to the stock login) and warned about —
|
|
207
|
+
* never thrown: this runs on every app-config serve and hot reload, and
|
|
208
|
+
* `himalaya-dev app validate` is where a bad id fails ([gateScreenIdProblem]). */
|
|
201
209
|
export declare function deriveAuthConfig(auth: {
|
|
202
210
|
providerId: string;
|
|
203
211
|
config: Record<string, unknown>;
|
|
204
|
-
} | undefined): AuthConfigBlock | undefined;
|
|
212
|
+
} | undefined, screenIds?: readonly string[]): AuthConfigBlock | undefined;
|
|
205
213
|
/** Derive a baseline NavigationConfig from the loaded app's derived meta. */
|
|
206
214
|
/** What `deriveNavigationConfig` needs to finish an app-level nav bundle ref.
|
|
207
215
|
*
|
|
@@ -94,8 +94,16 @@ export declare const auth: {
|
|
|
94
94
|
isAuthenticated(): Promise<boolean>;
|
|
95
95
|
/** The current access/member token (or null when anonymous). */
|
|
96
96
|
getAccessToken(): Promise<string | null>;
|
|
97
|
-
/** Sign in
|
|
98
|
-
|
|
97
|
+
/** Sign in, resolving with the new identity. With a real provider bound to the app's session
|
|
98
|
+
* gate this presents the real sign-in as a full-screen cover over the current screen — the
|
|
99
|
+
* app's `auth.config.gateScreenId` screen if set, else the stock login, opened on `intent`
|
|
100
|
+
* (default `"login"`) — and resolves once the user is signed in. Dismissing it rejects with
|
|
101
|
+
* `err.code === "cancelled"`; a second call while one is up rejects `"sign_in_in_progress"`.
|
|
102
|
+
* The calling worker survives the sign-in. Before the provider is bound it rejects
|
|
103
|
+
* `sign_in_unavailable`, as on web; only a shell with no session gate keeps the dev seam. */
|
|
104
|
+
signIn(opts?: {
|
|
105
|
+
intent?: "login" | "signup";
|
|
106
|
+
}): Promise<WixIdentity>;
|
|
99
107
|
/** Sign out — clears the member token (visitor session may persist). */
|
|
100
108
|
signOut(): Promise<WixIdentity>;
|
|
101
109
|
/** Mint/return a per-business signed instance for authorized Wix REST calls —
|
|
@@ -106,8 +114,8 @@ export declare const auth: {
|
|
|
106
114
|
*
|
|
107
115
|
* When the app provisions `real.auth`, it mints through the REAL Wix endpoint
|
|
108
116
|
* (the same `one-app-session-web` mint the Owner/Spaces bundles used ad-hoc),
|
|
109
|
-
* so
|
|
110
|
-
* native dev seam. */
|
|
117
|
+
* so it is observed like any other Wix call; otherwise (and on any failure) it
|
|
118
|
+
* uses the native dev seam. */
|
|
111
119
|
signedInstance(businessId: string, type?: WixSignedInstanceType): Promise<string | null>;
|
|
112
120
|
};
|
|
113
121
|
/** One business's scope, as `site.forSite(msid)` returns it.
|
|
@@ -177,7 +185,7 @@ export declare const site: {
|
|
|
177
185
|
* Only reaches businesses the signed-in user owns: the header names a business, and
|
|
178
186
|
* Wix refuses to mint an instance for one they do not. A consumer app (one Headless
|
|
179
187
|
* clientId, one site) does not mint per-site at all, so this is inert there — see
|
|
180
|
-
*
|
|
188
|
+
* the branded-lite-site-binding guide. */
|
|
181
189
|
forSite(msid: string): WixSiteScope;
|
|
182
190
|
};
|
|
183
191
|
export declare const monitoring: {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Why a `gateScreenId` value is not a usable screen id, or null when it is (or is absent). */
|
|
2
|
+
export declare function gateScreenIdShapeProblem(id: unknown): string | null;
|
|
3
|
+
/** Why `auth.config.gateScreenId` is not one of the app's exact screens, or null when it is (or is
|
|
4
|
+
* absent). One rule for every path — the served OTA authConfig, `app validate` and the auth bake:
|
|
5
|
+
* a release serves the exact screens (a templated route only for its build-time seed ids), and the
|
|
6
|
+
* OTA value overrides the baked one, so a templated gate id would mount a 404 gate in a release. */
|
|
7
|
+
export declare function gateScreenIdProblem(auth: {
|
|
8
|
+
providerId: string;
|
|
9
|
+
config: Record<string, unknown>;
|
|
10
|
+
} | undefined, screenIds: readonly string[]): string | null;
|
package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/define-app.d.ts
CHANGED
|
@@ -819,9 +819,24 @@ export interface ProdEnvironment {
|
|
|
819
819
|
export interface AuthProvider {
|
|
820
820
|
/** Stable id, e.g. "wix", "generic-oauth", "google", "<custom>". */
|
|
821
821
|
providerId: string;
|
|
822
|
-
/**
|
|
822
|
+
/**
|
|
823
|
+
* Provider-specific configuration, opaque to core — except two keys core lifts to the top of
|
|
824
|
+
* the baked `auth.json` and the OTA `authConfig`:
|
|
825
|
+
*
|
|
826
|
+
* - `required: true` gates the app's root on an authenticated session.
|
|
827
|
+
* - `gateScreenId: "<screen id>"` (#4651) names a screen the app ships as its own auth gate. A
|
|
828
|
+
* required-auth launch shows it, rendered by the ordinary screen host as a full-screen root,
|
|
829
|
+
* instead of the stock login, and a worker's mid-session `wixPlatform.auth.signIn()` presents
|
|
830
|
+
* it as a cover. It drives sign-in through the `auth.*` actions (`auth.signIn` with
|
|
831
|
+
* `params.intent: "login" | "signup"` opens the provider's own login UI in that mode); the
|
|
832
|
+
* credential still never passes through app code, the floor `screens` documents.
|
|
833
|
+
*/
|
|
823
834
|
config: Record<string, unknown>;
|
|
824
835
|
}
|
|
836
|
+
/** Validate the SHAPE of `auth.config.gateScreenId` (#4651): a non-empty string when present.
|
|
837
|
+
* Whether it names a screen the app ships is `gateScreenIdProblem`'s rule (the dev-server's app
|
|
838
|
+
* config, `himalaya-dev app validate` and the auth bake), which knows the app's screens. */
|
|
839
|
+
export declare function validateAuthGateScreen(auth: AuthProvider | undefined): void;
|
|
825
840
|
export interface TelemetrySink {
|
|
826
841
|
sinkId: string;
|
|
827
842
|
emit(event: TelemetryEvent): void | Promise<void>;
|
|
@@ -7143,6 +7143,15 @@ function validateDistribution(d, where = "distribution") {
|
|
|
7143
7143
|
}
|
|
7144
7144
|
}
|
|
7145
7145
|
|
|
7146
|
+
// ../../core/ts/src/auth-gate-screen.ts
|
|
7147
|
+
function gateScreenIdShapeProblem(id) {
|
|
7148
|
+
if (id === void 0) return null;
|
|
7149
|
+
if (typeof id !== "string" || id.trim().length === 0) {
|
|
7150
|
+
return `defineApp: auth.config.gateScreenId must be a non-empty screen id string, got ${JSON.stringify(id)}.`;
|
|
7151
|
+
}
|
|
7152
|
+
return null;
|
|
7153
|
+
}
|
|
7154
|
+
|
|
7146
7155
|
// ../../core/data-resources/src/base44/schema.ts
|
|
7147
7156
|
var BASE44_FIELD_TYPES = ["string", "number", "integer", "boolean", "array", "object"];
|
|
7148
7157
|
var BASE44_STRING_FORMATS = ["date", "date-time", "time", "email", "uri", "uuid", "file", "richtext"];
|
|
@@ -7462,6 +7471,10 @@ function resolveOrientationEnvelope(env) {
|
|
|
7462
7471
|
tablet: env?.tablet?.length ? env.tablet : DEFAULT_ORIENTATION_ENVELOPE.tablet
|
|
7463
7472
|
};
|
|
7464
7473
|
}
|
|
7474
|
+
function validateAuthGateScreen(auth) {
|
|
7475
|
+
const problem = gateScreenIdShapeProblem(auth?.config?.gateScreenId);
|
|
7476
|
+
if (problem) throw new Error(problem);
|
|
7477
|
+
}
|
|
7465
7478
|
function dataSchemaScopeOf(entity) {
|
|
7466
7479
|
if (entity.scope === "app" || entity.scope === "principal") return entity.scope;
|
|
7467
7480
|
return entity.encrypted ? "principal" : "app";
|
|
@@ -7702,6 +7715,7 @@ function validateConfigShape(config) {
|
|
|
7702
7715
|
validateDistribution(config.distribution, "defineApp: distribution");
|
|
7703
7716
|
}
|
|
7704
7717
|
validateLadderConfig(config);
|
|
7718
|
+
validateAuthGateScreen(config.auth);
|
|
7705
7719
|
if (config.tier5Cap) {
|
|
7706
7720
|
const c = config.tier5Cap;
|
|
7707
7721
|
if (c.percentageOfActiveScreens < 0 || c.percentageOfActiveScreens > 100) {
|
|
@@ -14687,6 +14701,7 @@ export {
|
|
|
14687
14701
|
tonalElevationAlpha,
|
|
14688
14702
|
validate,
|
|
14689
14703
|
validateAll,
|
|
14704
|
+
validateAuthGateScreen,
|
|
14690
14705
|
validateBase44Entities,
|
|
14691
14706
|
validateDistribution,
|
|
14692
14707
|
validateLaunchManifest,
|
|
@@ -200,9 +200,24 @@ var session = {
|
|
|
200
200
|
return { present: r?.present ?? false, msid: r?.msid ?? null };
|
|
201
201
|
}
|
|
202
202
|
};
|
|
203
|
-
|
|
204
|
-
|
|
203
|
+
var AUTH_REFUSAL_CODES = /* @__PURE__ */ new Set(["cancelled", "sign_in_in_progress", "sign_in_unavailable"]);
|
|
204
|
+
async function authTransition(method, params) {
|
|
205
|
+
const r = await call2(method, params).catch((e) => {
|
|
206
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
207
|
+
throw AUTH_REFUSAL_CODES.has(message) ? Object.assign(e instanceof Error ? e : new Error(message), { code: message }) : e;
|
|
208
|
+
});
|
|
209
|
+
if (typeof r?.error === "string" && r.error.length > 0) {
|
|
210
|
+
throw Object.assign(new Error(r.error), { code: r.error });
|
|
211
|
+
}
|
|
205
212
|
dropConductFlights();
|
|
213
|
+
if (method === "authSignIn" && typeof r?.authenticated === "boolean") {
|
|
214
|
+
return {
|
|
215
|
+
authenticated: r.authenticated,
|
|
216
|
+
type: r.type ?? (r.authenticated ? "member" : "anonymous"),
|
|
217
|
+
userId: r.userId || null,
|
|
218
|
+
email: r.email || null
|
|
219
|
+
};
|
|
220
|
+
}
|
|
206
221
|
return auth.getIdentity();
|
|
207
222
|
}
|
|
208
223
|
var auth = {
|
|
@@ -225,9 +240,15 @@ var auth = {
|
|
|
225
240
|
const r = await call2("authAccessToken");
|
|
226
241
|
return r?.token && r.token.length > 0 ? r.token : null;
|
|
227
242
|
},
|
|
228
|
-
/** Sign in
|
|
229
|
-
|
|
230
|
-
|
|
243
|
+
/** Sign in, resolving with the new identity. With a real provider bound to the app's session
|
|
244
|
+
* gate this presents the real sign-in as a full-screen cover over the current screen — the
|
|
245
|
+
* app's `auth.config.gateScreenId` screen if set, else the stock login, opened on `intent`
|
|
246
|
+
* (default `"login"`) — and resolves once the user is signed in. Dismissing it rejects with
|
|
247
|
+
* `err.code === "cancelled"`; a second call while one is up rejects `"sign_in_in_progress"`.
|
|
248
|
+
* The calling worker survives the sign-in. Before the provider is bound it rejects
|
|
249
|
+
* `sign_in_unavailable`, as on web; only a shell with no session gate keeps the dev seam. */
|
|
250
|
+
signIn(opts) {
|
|
251
|
+
return authTransition("authSignIn", { intent: opts?.intent ?? "login" });
|
|
231
252
|
},
|
|
232
253
|
/** Sign out — clears the member token (visitor session may persist). */
|
|
233
254
|
signOut() {
|
|
@@ -241,8 +262,8 @@ var auth = {
|
|
|
241
262
|
*
|
|
242
263
|
* When the app provisions `real.auth`, it mints through the REAL Wix endpoint
|
|
243
264
|
* (the same `one-app-session-web` mint the Owner/Spaces bundles used ad-hoc),
|
|
244
|
-
* so
|
|
245
|
-
* native dev seam. */
|
|
265
|
+
* so it is observed like any other Wix call; otherwise (and on any failure) it
|
|
266
|
+
* uses the native dev seam. */
|
|
246
267
|
async signedInstance(businessId, type = "User") {
|
|
247
268
|
if (isMemberReal("auth")) {
|
|
248
269
|
try {
|
|
@@ -341,7 +362,7 @@ var site = {
|
|
|
341
362
|
* Only reaches businesses the signed-in user owns: the header names a business, and
|
|
342
363
|
* Wix refuses to mint an instance for one they do not. A consumer app (one Headless
|
|
343
364
|
* clientId, one site) does not mint per-site at all, so this is inert there — see
|
|
344
|
-
*
|
|
365
|
+
* the branded-lite-site-binding guide. */
|
|
345
366
|
forSite(msid) {
|
|
346
367
|
const scoped = (msid ?? "").trim();
|
|
347
368
|
return {
|
package/dist/cli.mjs
CHANGED
|
@@ -18675,7 +18675,6 @@ function resolveIdiom(tokens2, ctx = {}) {
|
|
|
18675
18675
|
var IDIOM_CONTEXTS, UNSAFE_KEYS;
|
|
18676
18676
|
var init_idiom = __esm({
|
|
18677
18677
|
"../../core/ts/src/idiom.ts"() {
|
|
18678
|
-
"use strict";
|
|
18679
18678
|
IDIOM_CONTEXTS = {
|
|
18680
18679
|
ios: { native: ["ios"] },
|
|
18681
18680
|
android: { native: ["material"] },
|
|
@@ -31137,6 +31136,28 @@ var init_l10n = __esm({
|
|
|
31137
31136
|
}
|
|
31138
31137
|
});
|
|
31139
31138
|
|
|
31139
|
+
// ../../core/ts/src/auth-gate-screen.ts
|
|
31140
|
+
function gateScreenIdShapeProblem(id) {
|
|
31141
|
+
if (id === void 0) return null;
|
|
31142
|
+
if (typeof id !== "string" || id.trim().length === 0) {
|
|
31143
|
+
return `defineApp: auth.config.gateScreenId must be a non-empty screen id string, got ${JSON.stringify(id)}.`;
|
|
31144
|
+
}
|
|
31145
|
+
return null;
|
|
31146
|
+
}
|
|
31147
|
+
function gateScreenIdProblem(auth, screenIds) {
|
|
31148
|
+
const id = auth?.config?.gateScreenId;
|
|
31149
|
+
if (id === void 0) return null;
|
|
31150
|
+
const shape = gateScreenIdShapeProblem(id);
|
|
31151
|
+
if (shape) return shape;
|
|
31152
|
+
const gateId = id;
|
|
31153
|
+
if (screenIds.includes(gateId)) return null;
|
|
31154
|
+
return `defineApp: auth.config.gateScreenId is "${gateId}", which is not one of the app's exact screens \u2014 a required-auth launch would have no login to show (a release serves exact screens, so a templated route 404s). Name an exact screen, or drop gateScreenId to use the stock login.`;
|
|
31155
|
+
}
|
|
31156
|
+
var init_auth_gate_screen = __esm({
|
|
31157
|
+
"../../core/ts/src/auth-gate-screen.ts"() {
|
|
31158
|
+
}
|
|
31159
|
+
});
|
|
31160
|
+
|
|
31140
31161
|
// ../../core/ts/src/wix-push-links.ts
|
|
31141
31162
|
function replacementPingFamily(name) {
|
|
31142
31163
|
return RETIRED_PING_FAMILIES.has(name) ? DEFAULT_PING_APP_NAME : void 0;
|
|
@@ -31328,17 +31349,21 @@ function deriveTelemetryConfig(app) {
|
|
|
31328
31349
|
}
|
|
31329
31350
|
return cfg;
|
|
31330
31351
|
}
|
|
31331
|
-
function deriveAuthConfig(auth) {
|
|
31352
|
+
function deriveAuthConfig(auth, screenIds) {
|
|
31332
31353
|
if (!auth?.providerId) return void 0;
|
|
31333
31354
|
const config = {};
|
|
31334
31355
|
for (const [key3, value] of Object.entries(auth.config ?? {})) {
|
|
31335
|
-
if (key3 === "required") continue;
|
|
31356
|
+
if (key3 === "required" || key3 === "gateScreenId") continue;
|
|
31336
31357
|
if (AUTH_SECRET_KEY_RE.test(key3)) continue;
|
|
31337
31358
|
config[key3] = value;
|
|
31338
31359
|
}
|
|
31360
|
+
const gateScreenId = auth.config?.gateScreenId;
|
|
31361
|
+
const problem = typeof gateScreenId === "string" && screenIds ? gateScreenIdProblem(auth, screenIds) : null;
|
|
31362
|
+
if (problem) console.warn(`[app-config] ${problem} \u2014 serving the stock login instead.`);
|
|
31339
31363
|
return {
|
|
31340
31364
|
providerId: auth.providerId,
|
|
31341
31365
|
required: auth.config?.required === true,
|
|
31366
|
+
...typeof gateScreenId === "string" && gateScreenId.length > 0 && !problem ? { gateScreenId } : {},
|
|
31342
31367
|
config
|
|
31343
31368
|
};
|
|
31344
31369
|
}
|
|
@@ -31448,7 +31473,7 @@ function deriveNavigationConfig(app, bundleCtx) {
|
|
|
31448
31473
|
if (app.homeScreenId) config.homeScreenId = app.homeScreenId;
|
|
31449
31474
|
if (app.label) config.name = app.label;
|
|
31450
31475
|
config.backAffordance = { enabled: true };
|
|
31451
|
-
const authConfig = deriveAuthConfig(app.auth);
|
|
31476
|
+
const authConfig = deriveAuthConfig(app.auth, app.screenIds);
|
|
31452
31477
|
if (authConfig !== void 0) config.authConfig = authConfig;
|
|
31453
31478
|
if (app.iap !== void 0) config.iapConfig = app.iap;
|
|
31454
31479
|
if (app.cashier !== void 0) config.cashierConfig = app.cashier;
|
|
@@ -31539,6 +31564,7 @@ var init_app_config = __esm({
|
|
|
31539
31564
|
"../../core/dev-server/src/app-config.ts"() {
|
|
31540
31565
|
init_wix_cache_policy();
|
|
31541
31566
|
init_l10n();
|
|
31567
|
+
init_auth_gate_screen();
|
|
31542
31568
|
init_preview_surfaces();
|
|
31543
31569
|
init_wix_push_links();
|
|
31544
31570
|
SHARED_WIX_SENTRY_DSN = "https://5dfa4f23057c43149b6219c07d177472@sentry.io/84240";
|
|
@@ -32305,6 +32331,7 @@ var init_define_app = __esm({
|
|
|
32305
32331
|
"../../core/ts/src/define-app.ts"() {
|
|
32306
32332
|
init_locale();
|
|
32307
32333
|
init_distribution();
|
|
32334
|
+
init_auth_gate_screen();
|
|
32308
32335
|
init_schema2();
|
|
32309
32336
|
init_base44_entities();
|
|
32310
32337
|
init_src3();
|
|
@@ -162443,33 +162470,33 @@ var init_preview_assets_generated = __esm({
|
|
|
162443
162470
|
"../../packages/serve/src/preview-assets.generated.ts"() {
|
|
162444
162471
|
init_preview_assets_format();
|
|
162445
162472
|
PREVIEW_ASSET_MANIFEST = [
|
|
162446
|
-
{ key: "assets/DashboardHost-
|
|
162447
|
-
{ key: "assets/DevDrawer-
|
|
162448
|
-
{ key: "assets/IdiomCompare-
|
|
162449
|
-
{ key: "assets/LightboxViewer-
|
|
162450
|
-
{ key: "assets/PhonePreviewControl-
|
|
162451
|
-
{ key: "assets/SchemeCompare
|
|
162452
|
-
{ key: "assets/index-
|
|
162453
|
-
{ key: "assets/pdf-
|
|
162454
|
-
{ key: "assets/pdf.worker.min-BQa_JDET.js", contentType: "application/javascript; charset=utf-8", offset:
|
|
162455
|
-
{ key: "assets/pdf.worker.min-BmVo14Nb.mjs", contentType: "application/javascript; charset=utf-8", offset:
|
|
162456
|
-
{ key: "assets/pdfDocument-
|
|
162457
|
-
{ key: "assets/pdfFetch-Cc8i1I1h.js", contentType: "application/javascript; charset=utf-8", offset:
|
|
162458
|
-
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset:
|
|
162459
|
-
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset:
|
|
162460
|
-
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset:
|
|
162461
|
-
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
162462
|
-
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset:
|
|
162463
|
-
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset:
|
|
162464
|
-
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
162465
|
-
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset:
|
|
162466
|
-
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
162467
|
-
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset:
|
|
162468
|
-
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset:
|
|
162469
|
-
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
162470
|
-
{ key: "himi-sw.js", contentType: "application/javascript; charset=utf-8", offset:
|
|
162471
|
-
{ key: "index.html", contentType: "text/html; charset=utf-8", offset:
|
|
162472
|
-
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset:
|
|
162473
|
+
{ key: "assets/DashboardHost-V5OQ2K0K.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 2916, sha256: "51ffc72d485d4ef05c15c2da0d9435512721fa7b01334bd732ec1b65f19a165f" },
|
|
162474
|
+
{ key: "assets/DevDrawer-nAjavZLQ.js", contentType: "application/javascript; charset=utf-8", offset: 2924, length: 16744, sha256: "6fc1ae053f7f867093be7edd0cbc65121817adf72eb334af01c460bbdc4242d7" },
|
|
162475
|
+
{ key: "assets/IdiomCompare-CBKM_S6c.js", contentType: "application/javascript; charset=utf-8", offset: 19668, length: 1892, sha256: "55cbee8a082eb538f24cce371cd8cb86cf65dfbf7529e0ca2950507025627879" },
|
|
162476
|
+
{ key: "assets/LightboxViewer-d79GF3xc.js", contentType: "application/javascript; charset=utf-8", offset: 21560, length: 8132, sha256: "da5c8e29fa275b18467b2fc2793b74ebafead3357b1279f4465c0a2c3aab2a2d" },
|
|
162477
|
+
{ key: "assets/PhonePreviewControl-Cucnf6Lt.js", contentType: "application/javascript; charset=utf-8", offset: 29692, length: 37729, sha256: "ffb76986217eda36654aee1f77d9a69161fb38fda429becc35fa50603863c1ff" },
|
|
162478
|
+
{ key: "assets/SchemeCompare-Dj7pGZhQ.js", contentType: "application/javascript; charset=utf-8", offset: 67421, length: 1824, sha256: "61a467006401d83c9a168ccc3a7451d214d626a2bf85e1e3804a4dfe58985128" },
|
|
162479
|
+
{ key: "assets/index-hGM0n8mX.js", contentType: "application/javascript; charset=utf-8", offset: 69245, length: 1280687, sha256: "7dccbf4a3a5df57f59626ecee1e5a91b83e4626aea676212e6113a556b8a8c63" },
|
|
162480
|
+
{ key: "assets/pdf-BBk86PYz.js", contentType: "application/javascript; charset=utf-8", offset: 1349932, length: 488199, sha256: "8f41e595d8318953e766d0d4286e385f1d4053bfdd66981eb35b2ff3dacc3f5f" },
|
|
162481
|
+
{ key: "assets/pdf.worker.min-BQa_JDET.js", contentType: "application/javascript; charset=utf-8", offset: 1838131, length: 73, sha256: "41bcfda4f3c8c0a81c785ea87c69afc8e7d0ed8c333324aee94c273d881bb6aa" },
|
|
162482
|
+
{ key: "assets/pdf.worker.min-BmVo14Nb.mjs", contentType: "application/javascript; charset=utf-8", offset: 1838204, length: 1317034, sha256: "a33cfe728c584fdba4fcc1fd54bcdc2f9f2f13889ddbb5b2bd1d0f8cbe49b84e" },
|
|
162483
|
+
{ key: "assets/pdfDocument-DPaMY0jZ.js", contentType: "application/javascript; charset=utf-8", offset: 3155238, length: 3379, sha256: "f33b3711fc1c56bbf3dd45b013bb05e1d5bdca8843d975ce8a7c058025963b13" },
|
|
162484
|
+
{ key: "assets/pdfFetch-Cc8i1I1h.js", contentType: "application/javascript; charset=utf-8", offset: 3158617, length: 2266, sha256: "1d21ad008921942217c9eac0c35b1713773b9d89c71e3ab4412781f7bb88f463" },
|
|
162485
|
+
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 3160883, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
|
|
162486
|
+
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 3165493, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
|
|
162487
|
+
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 3654077, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
|
|
162488
|
+
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 3745001, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
|
|
162489
|
+
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 3835985, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
|
|
162490
|
+
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 3926965, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
|
|
162491
|
+
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 4017837, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
|
|
162492
|
+
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 4108817, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
|
|
162493
|
+
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 4217453, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
|
|
162494
|
+
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 4326537, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
|
|
162495
|
+
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 4435585, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
|
|
162496
|
+
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 4543285, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
|
|
162497
|
+
{ key: "himi-sw.js", contentType: "application/javascript; charset=utf-8", offset: 4631393, length: 6748, sha256: "4a92459977d7cefa1a6a7e020c3a63509737f083b3f2773557c1a5771665811a" },
|
|
162498
|
+
{ key: "index.html", contentType: "text/html; charset=utf-8", offset: 4638141, length: 4947, sha256: "62d2720e80f14dbdf428b7ca55b4b8ce77f5fe8db1d89ca5d1b96d1886c6ce93" },
|
|
162499
|
+
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 4643088, length: 17786, sha256: "084107ca997628c248f1b0ba3a7494744850df39fad813546ab8bdb82a6058da" }
|
|
162473
162500
|
];
|
|
162474
162501
|
}
|
|
162475
162502
|
});
|
|
Binary file
|
package/guides/hhp.md
CHANGED
|
@@ -147,10 +147,10 @@ transitions, haptics, and measurement remain explicit native modifiers.
|
|
|
147
147
|
|
|
148
148
|
Local HTML images resolve relative to their document and must live in the app's
|
|
149
149
|
declared assets directory. They use the existing content-addressed asset channel.
|
|
150
|
-
The descriptor carries a host-less `/v1/asset/<sha>?app=<id>` URL. iOS
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
150
|
+
The descriptor carries a host-less `/v1/asset/<sha>?app=<id>` URL. iOS, Android, the
|
|
151
|
+
web host and the embed SDK resolve it against the serve origin, so it loads same-origin,
|
|
152
|
+
behind a gateway path prefix, or inside an embed. React Native and web dashboard widget
|
|
153
|
+
cards do not rebase it yet.
|
|
154
154
|
|
|
155
155
|
iOS and Android have no SVG image decoder. When an `<img>` points at a package
|
|
156
156
|
`.svg`, the compiler renders it to a PNG at 3x the SVG's intrinsic size, writes
|
|
@@ -5209,7 +5209,7 @@
|
|
|
5209
5209
|
"name": "auth",
|
|
5210
5210
|
"kind": "const",
|
|
5211
5211
|
"jsdoc": "",
|
|
5212
|
-
"decl": "export const auth = {\n /** Current identity (visitor vs member vs owner) + who. */\n async getIdentity(): Promise<WixIdentity> {\n const r = await call<Partial<WixIdentity>>(\"authIdentity\");\n return {\n authenticated: r?.authenticated ?? false,\n type: (r?.type as WixIdentityType) ?? \"anonymous\",\n userId: r?.userId ?? null,\n email: r?.email ?? null,\n };\n },\n /** True when a member/owner is signed in. */\n async isAuthenticated(): Promise<boolean> {\n return (await auth.getIdentity()).authenticated;\n },\n /** The current access/member token (or null when anonymous). */\n async getAccessToken(): Promise<string | null> {\n const r = await call<{ token?: string }>(\"authAccessToken\");\n return r?.token && r.token.length > 0 ? r.token : null;\n },\n /** Sign in
|
|
5212
|
+
"decl": "export const auth = {\n /** Current identity (visitor vs member vs owner) + who. */\n async getIdentity(): Promise<WixIdentity> {\n const r = await call<Partial<WixIdentity>>(\"authIdentity\");\n return {\n authenticated: r?.authenticated ?? false,\n type: (r?.type as WixIdentityType) ?? \"anonymous\",\n userId: r?.userId ?? null,\n email: r?.email ?? null,\n };\n },\n /** True when a member/owner is signed in. */\n async isAuthenticated(): Promise<boolean> {\n return (await auth.getIdentity()).authenticated;\n },\n /** The current access/member token (or null when anonymous). */\n async getAccessToken(): Promise<string | null> {\n const r = await call<{ token?: string }>(\"authAccessToken\");\n return r?.token && r.token.length > 0 ? r.token : null;\n },\n /** Sign in, resolving with the new identity. With a real provider bound to the app's session\n * gate this presents the real sign-in as a full-screen cover over the current screen — the\n * app's `auth.config.gateScreenId` screen if set, else the stock login, opened on `intent`\n * (default `\"login\"`) — and resolves once the user is signed in. Dismissing it rejects with\n * `err.code === \"cancelled\"`; a second call while one is up rejects `\"sign_in_in_progress\"`.\n * The calling worker survives the sign-in. Before the provider is bound it rejects\n * `sign_in_unavailable`, as on web; only a shell with no session gate keeps the dev seam. */\n signIn(opts?: { intent?: \"login\" | \"signup\" }): Promise<WixIdentity> {\n return authTransition(\"authSignIn\", { intent: opts?.intent ?? \"login\" });\n },\n /** Sign out — clears the member token (visitor session may persist). */\n signOut(): Promise<WixIdentity> { return authTransition(\"authSignOut\"); },\n /** Mint/return a per-business signed instance for authorized Wix REST calls —\n * the ONE canonical worker-facing signed-instance accessor (RFC 0043 D3). A\n * worker never hand-rolls the mint HTTP; it calls this. `type` is the full Wix\n * identity matrix (owner=`User`, member, visitor, plus the Velo-scoped\n * variants) — mirrors @himalaya/wix-auth `SignedInstanceType`.\n *\n * When the app provisions `real.auth`, it mints through the REAL Wix endpoint\n * (the same `one-app-session-web` mint the Owner/Spaces bundles used ad-hoc),\n * so it is observed like any other Wix call; otherwise (and on any failure) it\n * uses the native dev seam. */\n async signedInstance(businessId: string, type: WixSignedInstanceType = \"User\"): Promise<string | null> {\n if (isMemberReal(\"auth\")) {\n try {\n const r = await realWix<{ signedInstance?: string }>(\n \"GET\",\n `https://apps.wix.com/_api/one-app-session-web/v3/businesses/${encodeURIComponent(businessId)}/signed-instance?signed_instance_type=${type}`,\n );\n if (typeof r?.signedInstance === \"string\" && r.signedInstance.length > 0) return r.signedInstance;\n } catch { /* fall through to the dev seam */ }\n }\n const r = await call<{ signedInstance?: string }>(\"authSignedInstance\", { businessId, type });\n return r?.signedInstance && r.signedInstance.length > 0 ? r.signedInstance : null;\n },\n};"
|
|
5213
5213
|
},
|
|
5214
5214
|
{
|
|
5215
5215
|
"name": "WixSiteScope",
|
|
@@ -5227,7 +5227,7 @@
|
|
|
5227
5227
|
"name": "site",
|
|
5228
5228
|
"kind": "const",
|
|
5229
5229
|
"jsdoc": "",
|
|
5230
|
-
"decl": "export const site = {\n /** Scope to a business by metaSiteId; resolves after the per-site instance mints. */\n setActiveSite(msid: string): Promise<{ ok: boolean; msid: string }> { return scopeToSite(msid); },\n /** The metaSiteId currently scoped (\"\" if none). */\n async activeSite(): Promise<string> {\n const r = await call<{ msid?: string }>(\"siteActive\");\n return r?.msid ?? \"\";\n },\n /** The customer's business/site info (identity + locale + contact) from Wix Site\n * Properties v4 (RFC 0048). Unlike bi/experiments, this is a plain REST GET: it\n * rides the wixApi transport — the same chokepoint the dev gateway observes /\n * mocks and prod binds — scoped to the active site's `User` signed instance, so\n * there is no native dev seam and no `real.site` flag. Returns `null` when no Wix\n * transport is installed (a non-Wix app) or the call fails, so callers degrade\n * gracefully. The ONE door for business info (RFC 0043) — a worker should call\n * this rather than hand-rolling `wixApi.call(\".../site-properties/...\")`. */\n async getBusinessInfo(): Promise<WixBusinessInfo | null> {\n if (typeof wpHost().wixApi?.call !== \"function\") return null;\n try {\n const res = await realWix<{ properties?: RawSiteProps } & RawSiteProps>(\n \"GET\", \"/site-properties/v4/properties\",\n );\n return parseBusinessInfo(res);\n } catch {\n return null;\n }\n },\n\n /** A handle that runs calls against ONE business, without moving the active site.\n *\n * `setActiveSite` re-scopes the whole process — every later call, every worker, the\n
|
|
5230
|
+
"decl": "export const site = {\n /** Scope to a business by metaSiteId; resolves after the per-site instance mints. */\n setActiveSite(msid: string): Promise<{ ok: boolean; msid: string }> { return scopeToSite(msid); },\n /** The metaSiteId currently scoped (\"\" if none). */\n async activeSite(): Promise<string> {\n const r = await call<{ msid?: string }>(\"siteActive\");\n return r?.msid ?? \"\";\n },\n /** The customer's business/site info (identity + locale + contact) from Wix Site\n * Properties v4 (RFC 0048). Unlike bi/experiments, this is a plain REST GET: it\n * rides the wixApi transport — the same chokepoint the dev gateway observes /\n * mocks and prod binds — scoped to the active site's `User` signed instance, so\n * there is no native dev seam and no `real.site` flag. Returns `null` when no Wix\n * transport is installed (a non-Wix app) or the call fails, so callers degrade\n * gracefully. The ONE door for business info (RFC 0043) — a worker should call\n * this rather than hand-rolling `wixApi.call(\".../site-properties/...\")`. */\n async getBusinessInfo(): Promise<WixBusinessInfo | null> {\n if (typeof wpHost().wixApi?.call !== \"function\") return null;\n try {\n const res = await realWix<{ properties?: RawSiteProps } & RawSiteProps>(\n \"GET\", \"/site-properties/v4/properties\",\n );\n return parseBusinessInfo(res);\n } catch {\n return null;\n }\n },\n\n /** A handle that runs calls against ONE business, without moving the active site.\n *\n * `setActiveSite` re-scopes the whole process — every later call, every worker, the\n * conducted cache and the entity cache all move with it. That is right for \"the owner\n * picked a business to manage\", and wrong for \"show me tonight's covers across all\n * three restaurants\": a rollup needs N businesses readable AT ONCE, and switching\n * between them to read each one serially is both slow and destructive of the scope the\n * user is actually in.\n *\n * The returned object IS a `WixSiteScope`, so it can be handed straight to a generated\n * client as its options bag — `searchOrders(req, site.forSite(msid))` — and it also\n * carries `call` for a raw path the typed clients do not cover. Fan several out with\n * `Promise.all` and each one keeps its own business.\n *\n * Only reaches businesses the signed-in user owns: the header names a business, and\n * Wix refuses to mint an instance for one they do not. A consumer app (one Headless\n * clientId, one site) does not mint per-site at all, so this is inert there — see\n * the branded-lite-site-binding guide. */\n forSite(msid: string): WixSiteScope {\n const scoped = (msid ?? \"\").trim();\n return {\n site: scoped,\n async call<T>(method: string, path: string, body?: unknown): Promise<T> {\n const api = wpHost().wixApi;\n if (!api) throw new Error(\"wixApi bridge unavailable\");\n // A blank msid would silently read the AMBIENT business, which is the one\n // failure mode a cross-site rollup cannot tolerate: it would attribute one\n // business's rows to another with nothing in the response to show for it.\n if (!scoped) throw new Error(\"site.forSite: a metaSiteId is required\");\n return (await api.call(method, path, body, { \"wix-site-id\": scoped })) as T;\n },\n };\n },\n};"
|
|
5231
5231
|
},
|
|
5232
5232
|
{
|
|
5233
5233
|
"name": "monitoring",
|
|
@@ -54,4 +54,4 @@ the SDK sources, so it matches the shipped SDKs.
|
|
|
54
54
|
- [`ui`](https://apps.wix.com/_api/himi-serve/authoring/resource/web-sdk%2Fui?format=md) — Imperative popup capability. 2 methods · not in Brandy.
|
|
55
55
|
- [`wix_cashier`](https://apps.wix.com/_api/himi-serve/authoring/resource/web-sdk%2Fwix_cashier?format=md) — Native cashier. 2 methods.
|
|
56
56
|
- [`wix_chat`](https://apps.wix.com/_api/himi-serve/authoring/resource/web-sdk%2Fwix_chat?format=md) — Host-owned realtime Chat event subscriptions. 2 methods.
|
|
57
|
-
- [`wix_platform`](https://apps.wix.com/_api/himi-serve/authoring/resource/web-sdk%2Fwix_platform?format=md) — Wix Platform SDK, worker-facing bindings.
|
|
57
|
+
- [`wix_platform`](https://apps.wix.com/_api/himi-serve/authoring/resource/web-sdk%2Fwix_platform?format=md) — Wix Platform SDK, worker-facing bindings. 27 methods · not in Brandy.
|
|
@@ -58,14 +58,14 @@ can't be built (see §Fail-closed). One place; all platforms read the baked outp
|
|
|
58
58
|
|
|
59
59
|
## Step 2 — bake → `auth.json`
|
|
60
60
|
|
|
61
|
-
`tools/auth-bake/bake-auth.ts` reads `config.ts`, lifts `required` to the top level, **scrubs any
|
|
61
|
+
`tools/auth-bake/bake-auth.ts` reads `config.ts`, lifts `required` (and `gateScreenId`, below) to the top level, **scrubs any
|
|
62
62
|
`secret`/`private` key**, and writes `auth.json` into the iOS bundle, Android assets, and (when
|
|
63
63
|
present) the macOS bundle resources:
|
|
64
64
|
|
|
65
65
|
```
|
|
66
66
|
node --import tsx tools/auth-bake/bake-auth.ts apps/<app> --ios apps/<app>/ios/<target> --android apps/<app>/android/<module> --macos apps/<app>/macos/<target>
|
|
67
67
|
```
|
|
68
|
-
`auth.json` = `{ providerId, required, config }`. Read by `TemplateAppBoot.loadBakedAuth()` (iOS
|
|
68
|
+
`auth.json` = `{ providerId, required, gateScreenId?, config }`. Read by `TemplateAppBoot.loadBakedAuth()` (iOS
|
|
69
69
|
and macOS) / `TemplateAuth.boot()` (Android).
|
|
70
70
|
|
|
71
71
|
## Step 3 — wire the gate (per platform)
|
|
@@ -76,13 +76,16 @@ and macOS) / `TemplateAuth.boot()` (Android).
|
|
|
76
76
|
instantiate via `AuthProviderRegistry.shared.instantiate(providerId:config:)`, `sessionGate.bind(to: provider)`,
|
|
77
77
|
set `sessionGate.formMode = .emailEntry` for native, and **bind the transport**:
|
|
78
78
|
`wixApiCapability = WixApiCapability(authProvider: provider, mobileContext: …)`.
|
|
79
|
-
- The SwiftUI root
|
|
79
|
+
- The SwiftUI root wraps its content in the core `AuthGateRoot(gate:required:gateScreen:content:)`, which
|
|
80
|
+
shows the gate until `sessionGate.state` is authenticated (the stock `AuthGateView`, or the app's own gate
|
|
81
|
+
screen — below) and presents a worker's mid-session sign-in over the content.
|
|
80
82
|
|
|
81
83
|
### Android
|
|
82
84
|
- Gradle: add the `:himalaya-wix-auth` module (settings + `implementation(project(":himalaya-wix-auth"))`).
|
|
83
85
|
- In `Application.onCreate()`: `HimalayaWixAuth.register()` **before** `TemplateAuth.boot(applicationContext)`
|
|
84
86
|
(which reads `assets/auth.json`, instantiates via the registry, and `gate.bind(provider, scope)`).
|
|
85
|
-
- The root composition
|
|
87
|
+
- The root composition calls the core `AuthGateRoot(gate, required, gateScreen, content)` with
|
|
88
|
+
`TemplateAuth.gate` + `TemplateAuth.required` — the stock `AuthGateScreen` or the app's own gate screen.
|
|
86
89
|
- Bind the transport where you make Wix calls: `WixApiCapability(authProvider = provider)`.
|
|
87
90
|
|
|
88
91
|
### macOS
|
|
@@ -154,6 +157,55 @@ their own message; the primary button sends a new request, and the method picker
|
|
|
154
157
|
factor at any time. Dev seam accounts: `2fa-push@himalaya.dev` (approves) and
|
|
155
158
|
`2fa-push-deny@himalaya.dev` (declines), password `Passw0rd!`.
|
|
156
159
|
|
|
160
|
+
## Your own gate screen and mid-session sign-in (`gateScreenId`, `auth.signIn`)
|
|
161
|
+
|
|
162
|
+
Name a screen the app ships as its auth gate, and the stock login steps aside:
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
const native = WixNativeAuthProvider({ mode: "consumer", clientId: "…" });
|
|
166
|
+
// …
|
|
167
|
+
auth: { ...native, config: { ...native.config, required: true, gateScreenId: "welcome" } },
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
(The provider factories forward only their own keys, so `required` and `gateScreenId` go on the
|
|
171
|
+
returned block's `config`, which is what the bake and the OTA derivation read.)
|
|
172
|
+
|
|
173
|
+
`defineApp` checks the shape; the app-config derivation drops, and the auth bake refuses, a `gateScreenId`
|
|
174
|
+
that is not one of the app's exact screens (a templated route is never a gate screen: a release serves
|
|
175
|
+
exact screens). It is lifted next to `required` in `auth.json` and the OTA `authConfig`, read with
|
|
176
|
+
`AuthBoot.gateScreenId(baked:ota:)` (Kotlin: `AuthBoot.gateScreenId(baked, ota)`) into
|
|
177
|
+
`SessionGate.gateScreenId`. A required-auth launch then shows that screen — the ordinary screen host,
|
|
178
|
+
worker and bindings included, as a full-screen root with no tab bar. It must be an exact screen
|
|
179
|
+
(a release serves exact screens): the auth bake and the app validation gate refuse anything else.
|
|
180
|
+
|
|
181
|
+
The screen drives sign-in only through `auth.*` actions, which `sessionGate.registerAuthActions()`
|
|
182
|
+
installs on the dispatcher — the credential never passes through app code:
|
|
183
|
+
|
|
184
|
+
| Action | Does |
|
|
185
|
+
|---|---|
|
|
186
|
+
| `auth.signIn` `{ intent: "login" \| "signup" }` | opens the provider's own login in that mode — wix-native: the in-app form in sign-in / register mode, over the gate screen (with a Back, `auth_gate_back`); a hosted provider: its hosted page (`intent` is a hint) |
|
|
187
|
+
| `auth.cancel` | closes a mid-session sign-in (the worker's call rejects `cancelled`), else steps back to the gate screen |
|
|
188
|
+
| `auth.socialSignIn`, `auth.setFormMode`, `auth.forgotPassword`, `auth.continueWithEmail`, biometric verbs | the existing set, routed to the gate |
|
|
189
|
+
|
|
190
|
+
The credential-carrying actions (`auth.signInWithPassword`, `auth.register`, `auth.submit2FA`) are
|
|
191
|
+
deliberately **not** routed from screens: a screen's controls can bind their params to anything, so a
|
|
192
|
+
password typed into an app screen would pass through app code. A gate screen opens the provider's own
|
|
193
|
+
form with `auth.signIn`, and only that native form supplies a credential. The gate actions accept a
|
|
194
|
+
dispatch from a screen's own controls only — not from a worker, an agent, or a WebView page.
|
|
195
|
+
|
|
196
|
+
**Mid-session sign-in.** With a real provider bound to the gate, a worker's
|
|
197
|
+
`wixPlatform.auth.signIn({ intent })` presents the sign-in as a full-screen cover over the current screen —
|
|
198
|
+
the `gateScreenId` screen if set, else the stock gate — and resolves with the new identity once the gate is
|
|
199
|
+
authenticated. Closing it (`auth_signin_cover_close`) rejects with `err.code === "cancelled"`; a second
|
|
200
|
+
call while one is up rejects `sign_in_in_progress`. The calling worker survives. The cover is part of
|
|
201
|
+
`AuthGateRoot`, and while it is mounted it is what `capability.wix_platform.authSignIn` routes to: with no
|
|
202
|
+
provider bound to the gate (yet, on a cold launch, or at all) it rejects `sign_in_unavailable` — never the
|
|
203
|
+
dev seam's demo member. Only a shell with no `AuthGateRoot` keeps the dev seam; on web, so does a host
|
|
204
|
+
with no live Wix member bridge.
|
|
205
|
+
|
|
206
|
+
Shells are copied when an app is scaffolded: a new app's shell calls `AuthGateRoot`, while an app
|
|
207
|
+
scaffolded before keeps its inline stock gate until its root switches to the helper.
|
|
208
|
+
|
|
157
209
|
## Fail-closed (`required: true`)
|
|
158
210
|
|
|
159
211
|
If a required-auth app can't build its provider (unknown `providerId`, missing config key), boot sets a
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`@himalaya/wix-platform` is the T5-worker-facing surface of the Wix Platform SDK. It is
|
|
4
4
|
**platform-agnostic** — the same JS runs on iOS, Android, macOS and web, with **one documented
|
|
5
|
-
exception**:
|
|
5
|
+
exception**: `auth.signIn()` can reject, with an `err.code`, on every platform (see
|
|
6
6
|
[Real vs dev seam](#real-vs-dev-seam-and-best-effort) below). Each
|
|
7
7
|
member dispatches to the native `wix_platform` capability (with an on-device dev seam);
|
|
8
8
|
`bi`, `monitoring`, `session` and `auth` take their real backend when the app enables them
|
|
@@ -76,22 +76,37 @@ await monitoring.captureError("thing failed", { code: "E1" });
|
|
|
76
76
|
`real.deeplink` are ignored.
|
|
77
77
|
- `bi`, `monitoring`, and `auth` route through their native backends (Frog sink, Sentry
|
|
78
78
|
sink, `WixNativeAuthProvider`) rather than raw `wixApi`, but the calling contract is
|
|
79
|
-
identical — **except `auth.signIn()
|
|
79
|
+
identical — **except `auth.signIn()`, which can reject on every platform**, below.
|
|
80
80
|
|
|
81
|
-
### `auth.signIn()` on
|
|
81
|
+
### `auth.signIn({ intent })` on a real provider
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
On iOS, macOS and Android, when the shell has a real provider bound to its session gate (an app on the
|
|
84
|
+
core `AuthGateRoot`), `auth.signIn({ intent: "login" | "signup" })` presents the real sign-in as a
|
|
85
|
+
full-screen cover over the current screen and resolves with the signed-in identity. Closing it rejects with
|
|
86
|
+
`err.code === "cancelled"`, and a second concurrent call rejects `sign_in_in_progress` — so handle the
|
|
87
|
+
rejection. Before the boot has bound the provider (or in such a shell with none) it rejects
|
|
88
|
+
`sign_in_unavailable`; only a shell with no core `AuthGateRoot` keeps the dev seam's demo member. See
|
|
89
|
+
[wix-login-integration](wix-login-integration.md#your-own-gate-screen-and-mid-session-sign-in-gatescreenid-authsignin).
|
|
87
90
|
|
|
88
|
-
|
|
89
|
-
|
|
91
|
+
### `auth.signIn()` is the one member that rejects
|
|
92
|
+
|
|
93
|
+
`auth.signIn()` is the one member where the "never throws" rule above does not hold — on
|
|
94
|
+
native and on web alike, and always with an `err.code`:
|
|
95
|
+
|
|
96
|
+
- `cancelled` — the user closed the sign-in (native).
|
|
97
|
+
- `sign_in_in_progress` — another sign-in is already up (native).
|
|
98
|
+
- `sign_in_unavailable` — no sign-in can be shown: on native, before the provider is bound or
|
|
99
|
+
where the shell cannot present one; on web, always unless the member bridge already holds a
|
|
100
|
+
member (then it resolves and reports who). Web starts no session itself: it rejects both
|
|
101
|
+
when no member session can be started and when the member bridge is unreachable.
|
|
102
|
+
|
|
103
|
+
So a worker must handle it, and can branch on the code:
|
|
90
104
|
|
|
91
105
|
```js
|
|
92
106
|
try {
|
|
93
|
-
await auth.signIn();
|
|
94
|
-
} catch {
|
|
107
|
+
await auth.signIn({ intent: "login" });
|
|
108
|
+
} catch (err) {
|
|
109
|
+
if (err.code === "cancelled") return; // the user said no — leave the screen as it was
|
|
95
110
|
// "sign-in isn't available here" — render a real state, not a dead button.
|
|
96
111
|
}
|
|
97
112
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1471.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": "cd4d5ceeaf1823831031129d85d33f4d35a9aa4e5bfd8804fe964fe1"
|
|
75
75
|
}
|