@wix/himalaya-cli 0.1400.0 → 0.1402.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/stdlib/auth-providers/wix/src/auth-modalities.d.ts +13 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/auth-providers/wix/src/index.d.ts +11 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/auth-providers/wix/src/native-engine.d.ts +7 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/auth/src/copy.generated.d.ts +5 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/auth.mjs +5 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/screens.mjs +5 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-auth/worker.mjs +53 -12
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-auth.mjs +60 -12
- package/dist/cli.mjs +24 -24
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/wix-login-integration.md +42 -0
- package/package.json +2 -2
|
@@ -7,6 +7,8 @@ export declare function classifyAuthErrorCode(code: number): {
|
|
|
7
7
|
export type PushApprovalState = "approved" | "pending" | "denied" | "expired";
|
|
8
8
|
export interface AuthModalitiesConfig {
|
|
9
9
|
baseURL?: string;
|
|
10
|
+
/** Host of the Verification v1 API the push-approval poll reads (#4309). */
|
|
11
|
+
verificationBaseURL?: string;
|
|
10
12
|
fetchImpl?: typeof fetch;
|
|
11
13
|
now?: () => number;
|
|
12
14
|
sleep?: (ms: number) => Promise<void>;
|
|
@@ -14,6 +16,7 @@ export interface AuthModalitiesConfig {
|
|
|
14
16
|
}
|
|
15
17
|
export declare class WixAuthModalities {
|
|
16
18
|
private readonly baseURL;
|
|
19
|
+
private readonly verificationBaseURL;
|
|
17
20
|
private readonly fetchImpl;
|
|
18
21
|
private readonly sleep;
|
|
19
22
|
private readonly devMode;
|
|
@@ -26,8 +29,16 @@ export declare class WixAuthModalities {
|
|
|
26
29
|
/** Complete a magic-link login from the token in the opened link. */
|
|
27
30
|
verifyMagicLink(token: string): Promise<WixAccountSession>;
|
|
28
31
|
/** Push-based 2FA: poll for the user's approval on their trusted device. Loops
|
|
29
|
-
* until approved/denied/expired or `maxPolls` is hit.
|
|
30
|
-
|
|
32
|
+
* until approved/denied/expired or `maxPolls` is hit (default 60 × 5s = 5 minutes).
|
|
33
|
+
*
|
|
34
|
+
* #4309 — the wire Wix's own native client uses (mobile-native-core LegacyTwoFactor), and
|
|
35
|
+
* the one the native WixNativeAuthEngine polls: Verification v1 GetChallenge,
|
|
36
|
+
* `GET manage.wix.com/_api/verification-web/v1/challenges/get-challenge?verificationId=…`,
|
|
37
|
+
* keyed by the 2FA payload's `verificationId` (digits; `NativeAuthError.verificationId` on the
|
|
38
|
+
* needsTwoFactor challenge — not its `twoFAToken`). After "approved" the caller completes
|
|
39
|
+
* the login with ONE `/auth/m/verifycodeandlogin` carrying an empty code. The old
|
|
40
|
+
* `/auth/m/push2fa/status` route was never Wix's. */
|
|
41
|
+
pollPushApproval(verificationId: string, opts?: {
|
|
31
42
|
intervalMs?: number;
|
|
32
43
|
maxPolls?: number;
|
|
33
44
|
}): Promise<PushApprovalState>;
|
|
@@ -91,8 +91,18 @@ export interface WixNativeAuthConfig {
|
|
|
91
91
|
/** App URL scheme registered in the client's allowed redirect URIs — used by
|
|
92
92
|
* the (no-UI) sessionToken → member-token PKCE exchange. */
|
|
93
93
|
redirectUri?: string;
|
|
94
|
-
/** Federated providers to surface on the form.
|
|
94
|
+
/** Federated providers to surface on the form. The app shows only the ones that can run on
|
|
95
|
+
* the platform (#4309): Apple on iOS, Google once its module is linked and `google` names a
|
|
96
|
+
* client id. */
|
|
95
97
|
social?: SocialAuthProvider[];
|
|
98
|
+
/** Google OAuth client ids for "Continue with Google" (#4309). iOS registers `iosClientId`
|
|
99
|
+
* (with its reversed-id URL scheme in Info.plist); Android asks Credential Manager for a token
|
|
100
|
+
* for `serverClientId`, the WEB client Wix's `/oneapp/social/sign-in/google` accepts. Absent →
|
|
101
|
+
* the Google button is hidden on that platform. Baked into auth.json. */
|
|
102
|
+
google?: {
|
|
103
|
+
iosClientId?: string;
|
|
104
|
+
serverClientId?: string;
|
|
105
|
+
};
|
|
96
106
|
/** Override the Wix API host (staging). Default: https://www.wixapis.com. */
|
|
97
107
|
apiBase?: string;
|
|
98
108
|
/** PerimeterX automation token — one-app `x-px-access-token` captcha bypass for
|
|
@@ -27,9 +27,15 @@ export declare class NativeAuthError extends Error {
|
|
|
27
27
|
readonly twoFAMethod?: string;
|
|
28
28
|
/** Every enabled 2FA method (drives the picker when >1). */
|
|
29
29
|
readonly twoFAMethods?: string[];
|
|
30
|
+
/** #4309 — the push challenge's id (digits), when the payload carried one: what
|
|
31
|
+
* `WixAuthModalities.pollPushApproval` polls. */
|
|
32
|
+
readonly verificationId?: string;
|
|
30
33
|
constructor(kind: NativeAuthErrorKind, message: string, twoFAToken?: string, twoFAMethod?: string,
|
|
31
34
|
/** Every enabled 2FA method (drives the picker when >1). */
|
|
32
|
-
twoFAMethods?: string[]
|
|
35
|
+
twoFAMethods?: string[],
|
|
36
|
+
/** #4309 — the push challenge's id (digits), when the payload carried one: what
|
|
37
|
+
* `WixAuthModalities.pollPushApproval` polls. */
|
|
38
|
+
verificationId?: string);
|
|
33
39
|
}
|
|
34
40
|
export interface WixNativeAuthEngineConfig {
|
|
35
41
|
baseURL?: string;
|
|
@@ -14,6 +14,8 @@ declare const _default: {
|
|
|
14
14
|
readonly "auth.gate.sendCodeVia": "Send code via";
|
|
15
15
|
readonly "auth.gate.resendCode": "Didn't get it? Resend code";
|
|
16
16
|
readonly "auth.gate.field.code": "Verification code";
|
|
17
|
+
readonly "auth.gate.pushWaiting": "Approve the sign-in on your other device.";
|
|
18
|
+
readonly "auth.gate.pushResend": "Send a new request";
|
|
17
19
|
readonly "auth.gate.field.email": "Email";
|
|
18
20
|
readonly "auth.gate.field.name": "Name";
|
|
19
21
|
readonly "auth.gate.field.password": "Password";
|
|
@@ -58,6 +60,9 @@ declare const _default: {
|
|
|
58
60
|
readonly "auth.error.registrationFailed": "Registration failed ({code}).";
|
|
59
61
|
readonly "auth.error.twoFactorRequired": "Two-factor verification required.";
|
|
60
62
|
readonly "auth.error.noPendingVerification": "No pending verification.";
|
|
63
|
+
readonly "auth.error.pushDeclined": "The sign-in was declined on your other device.";
|
|
64
|
+
readonly "auth.error.pushExpired": "The approval request expired. Send a new one or choose another method.";
|
|
65
|
+
readonly "auth.error.pushUnavailable": "Push approval isn't available. Choose another method.";
|
|
61
66
|
readonly "auth.error.verificationCancelled": "Verification cancelled.";
|
|
62
67
|
readonly "auth.error.biometricSignInFirst": "Sign in before enabling biometric unlock.";
|
|
63
68
|
readonly "auth.error.noSessionToProtect": "No session to protect.";
|
|
@@ -129,6 +129,8 @@ var copy_generated_default = {
|
|
|
129
129
|
"auth.gate.sendCodeVia": "Send code via",
|
|
130
130
|
"auth.gate.resendCode": "Didn't get it? Resend code",
|
|
131
131
|
"auth.gate.field.code": "Verification code",
|
|
132
|
+
"auth.gate.pushWaiting": "Approve the sign-in on your other device.",
|
|
133
|
+
"auth.gate.pushResend": "Send a new request",
|
|
132
134
|
"auth.gate.field.email": "Email",
|
|
133
135
|
"auth.gate.field.name": "Name",
|
|
134
136
|
"auth.gate.field.password": "Password",
|
|
@@ -173,6 +175,9 @@ var copy_generated_default = {
|
|
|
173
175
|
"auth.error.registrationFailed": "Registration failed ({code}).",
|
|
174
176
|
"auth.error.twoFactorRequired": "Two-factor verification required.",
|
|
175
177
|
"auth.error.noPendingVerification": "No pending verification.",
|
|
178
|
+
"auth.error.pushDeclined": "The sign-in was declined on your other device.",
|
|
179
|
+
"auth.error.pushExpired": "The approval request expired. Send a new one or choose another method.",
|
|
180
|
+
"auth.error.pushUnavailable": "Push approval isn't available. Choose another method.",
|
|
176
181
|
"auth.error.verificationCancelled": "Verification cancelled.",
|
|
177
182
|
"auth.error.biometricSignInFirst": "Sign in before enabling biometric unlock.",
|
|
178
183
|
"auth.error.noSessionToProtect": "No session to protect.",
|
|
@@ -140,6 +140,8 @@ var copy_generated_default = {
|
|
|
140
140
|
"auth.gate.sendCodeVia": "Send code via",
|
|
141
141
|
"auth.gate.resendCode": "Didn't get it? Resend code",
|
|
142
142
|
"auth.gate.field.code": "Verification code",
|
|
143
|
+
"auth.gate.pushWaiting": "Approve the sign-in on your other device.",
|
|
144
|
+
"auth.gate.pushResend": "Send a new request",
|
|
143
145
|
"auth.gate.field.email": "Email",
|
|
144
146
|
"auth.gate.field.name": "Name",
|
|
145
147
|
"auth.gate.field.password": "Password",
|
|
@@ -184,6 +186,9 @@ var copy_generated_default = {
|
|
|
184
186
|
"auth.error.registrationFailed": "Registration failed ({code}).",
|
|
185
187
|
"auth.error.twoFactorRequired": "Two-factor verification required.",
|
|
186
188
|
"auth.error.noPendingVerification": "No pending verification.",
|
|
189
|
+
"auth.error.pushDeclined": "The sign-in was declined on your other device.",
|
|
190
|
+
"auth.error.pushExpired": "The approval request expired. Send a new one or choose another method.",
|
|
191
|
+
"auth.error.pushUnavailable": "Push approval isn't available. Choose another method.",
|
|
187
192
|
"auth.error.verificationCancelled": "Verification cancelled.",
|
|
188
193
|
"auth.error.biometricSignInFirst": "Sign in before enabling biometric unlock.",
|
|
189
194
|
"auth.error.noSessionToProtect": "No session to protect.",
|
|
@@ -167,12 +167,13 @@ var DeviceAuthClient = class {
|
|
|
167
167
|
|
|
168
168
|
// ../../stdlib/auth-providers/wix/src/native-engine.ts
|
|
169
169
|
var NativeAuthError = class extends Error {
|
|
170
|
-
constructor(kind, message, twoFAToken, twoFAMethod, twoFAMethods) {
|
|
170
|
+
constructor(kind, message, twoFAToken, twoFAMethod, twoFAMethods, verificationId) {
|
|
171
171
|
super(message);
|
|
172
172
|
this.kind = kind;
|
|
173
173
|
this.twoFAToken = twoFAToken;
|
|
174
174
|
this.twoFAMethod = twoFAMethod;
|
|
175
175
|
this.twoFAMethods = twoFAMethods;
|
|
176
|
+
this.verificationId = verificationId;
|
|
176
177
|
this.name = "NativeAuthError";
|
|
177
178
|
}
|
|
178
179
|
};
|
|
@@ -270,12 +271,15 @@ var WixNativeAuthEngine = class {
|
|
|
270
271
|
if (payload.twoFAToken && json.success !== true) {
|
|
271
272
|
const current = payload.currentTwoFAMethod ?? "sms";
|
|
272
273
|
const methods = payload.enabledTwoFAMethods ?? [current];
|
|
274
|
+
const id = payload.verificationId;
|
|
275
|
+
const verificationId = (typeof id === "string" || typeof id === "number") && /^\d+$/.test(String(id)) ? String(id) : void 0;
|
|
273
276
|
throw new NativeAuthError(
|
|
274
277
|
"needsTwoFactor",
|
|
275
278
|
"Two-factor verification required.",
|
|
276
279
|
payload.twoFAToken,
|
|
277
280
|
current,
|
|
278
|
-
methods
|
|
281
|
+
methods,
|
|
282
|
+
verificationId
|
|
279
283
|
);
|
|
280
284
|
}
|
|
281
285
|
if (json.success !== true || !payload.guid) {
|
|
@@ -472,10 +476,12 @@ function classifyAuthErrorCode(code) {
|
|
|
472
476
|
var WixAuthModalities = class {
|
|
473
477
|
constructor(config = {}) {
|
|
474
478
|
__publicField(this, "baseURL");
|
|
479
|
+
__publicField(this, "verificationBaseURL");
|
|
475
480
|
__publicField(this, "fetchImpl");
|
|
476
481
|
__publicField(this, "sleep");
|
|
477
482
|
__publicField(this, "devMode");
|
|
478
483
|
this.baseURL = config.baseURL ?? "https://users.wix.com";
|
|
484
|
+
this.verificationBaseURL = config.verificationBaseURL ?? "https://manage.wix.com";
|
|
479
485
|
this.fetchImpl = config.fetchImpl ?? globalThis.fetch;
|
|
480
486
|
this.sleep = config.sleep ?? engineSleep("WixAuthModalities");
|
|
481
487
|
this.devMode = config.devMode ?? false;
|
|
@@ -500,25 +506,60 @@ var WixAuthModalities = class {
|
|
|
500
506
|
return { userId: p.guid ?? "", email: p.email ?? "", accessToken: access, refreshToken: p.wixSession2 ?? "" };
|
|
501
507
|
}
|
|
502
508
|
/** Push-based 2FA: poll for the user's approval on their trusted device. Loops
|
|
503
|
-
* until approved/denied/expired or `maxPolls` is hit.
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
509
|
+
* until approved/denied/expired or `maxPolls` is hit (default 60 × 5s = 5 minutes).
|
|
510
|
+
*
|
|
511
|
+
* #4309 — the wire Wix's own native client uses (mobile-native-core LegacyTwoFactor), and
|
|
512
|
+
* the one the native WixNativeAuthEngine polls: Verification v1 GetChallenge,
|
|
513
|
+
* `GET manage.wix.com/_api/verification-web/v1/challenges/get-challenge?verificationId=…`,
|
|
514
|
+
* keyed by the 2FA payload's `verificationId` (digits; `NativeAuthError.verificationId` on the
|
|
515
|
+
* needsTwoFactor challenge — not its `twoFAToken`). After "approved" the caller completes
|
|
516
|
+
* the login with ONE `/auth/m/verifycodeandlogin` carrying an empty code. The old
|
|
517
|
+
* `/auth/m/push2fa/status` route was never Wix's. */
|
|
518
|
+
async pollPushApproval(verificationId, opts = {}) {
|
|
519
|
+
const interval = opts.intervalMs ?? 5e3;
|
|
520
|
+
const maxPolls = opts.maxPolls ?? 60;
|
|
521
|
+
if (!this.devMode && !/^\d+$/.test(verificationId)) {
|
|
522
|
+
throw new NativeAuthError("unknown", "Push approval isn't available. Choose another method.");
|
|
523
|
+
}
|
|
507
524
|
for (let i = 0; i < maxPolls; i++) {
|
|
508
|
-
const state = await this.pushStatusOnce(
|
|
525
|
+
const state = await this.pushStatusOnce(verificationId, i);
|
|
509
526
|
if (state !== "pending") return state;
|
|
510
527
|
await this.sleep(interval);
|
|
511
528
|
}
|
|
512
529
|
return "expired";
|
|
513
530
|
}
|
|
514
|
-
async pushStatusOnce(
|
|
531
|
+
async pushStatusOnce(verificationId, poll) {
|
|
515
532
|
if (this.devMode) {
|
|
516
|
-
if (
|
|
533
|
+
if (verificationId === "deny") return "denied";
|
|
517
534
|
return poll >= 1 ? "approved" : "pending";
|
|
518
535
|
}
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
536
|
+
let res;
|
|
537
|
+
try {
|
|
538
|
+
res = await this.fetchImpl(
|
|
539
|
+
`${this.verificationBaseURL}/_api/verification-web/v1/challenges/get-challenge?verificationId=${verificationId}`,
|
|
540
|
+
{ method: "GET", headers: { Accept: "application/json" } }
|
|
541
|
+
);
|
|
542
|
+
} catch {
|
|
543
|
+
return "pending";
|
|
544
|
+
}
|
|
545
|
+
if (res.status === 404) return "expired";
|
|
546
|
+
if (!res.ok) return "pending";
|
|
547
|
+
let j = {};
|
|
548
|
+
try {
|
|
549
|
+
j = JSON.parse(await res.text());
|
|
550
|
+
} catch {
|
|
551
|
+
return "pending";
|
|
552
|
+
}
|
|
553
|
+
switch (j.challenge?.approvalChallenge?.status) {
|
|
554
|
+
case "APPROVED":
|
|
555
|
+
return "approved";
|
|
556
|
+
case "DECLINED":
|
|
557
|
+
return "denied";
|
|
558
|
+
case "EXPIRED":
|
|
559
|
+
return "expired";
|
|
560
|
+
default:
|
|
561
|
+
return "pending";
|
|
562
|
+
}
|
|
522
563
|
}
|
|
523
564
|
/** Device-login: approve a login started on another device (confirm-on-device). */
|
|
524
565
|
async confirmDeviceLogin(userCode, authToken) {
|
|
@@ -35,12 +35,13 @@ function dualDomainAuthorizeUrls(clientIds, redirectUri, opts = {}, endpoint = O
|
|
|
35
35
|
|
|
36
36
|
// ../../stdlib/auth-providers/wix/src/native-engine.ts
|
|
37
37
|
var NativeAuthError = class extends Error {
|
|
38
|
-
constructor(kind, message, twoFAToken, twoFAMethod, twoFAMethods) {
|
|
38
|
+
constructor(kind, message, twoFAToken, twoFAMethod, twoFAMethods, verificationId) {
|
|
39
39
|
super(message);
|
|
40
40
|
this.kind = kind;
|
|
41
41
|
this.twoFAToken = twoFAToken;
|
|
42
42
|
this.twoFAMethod = twoFAMethod;
|
|
43
43
|
this.twoFAMethods = twoFAMethods;
|
|
44
|
+
this.verificationId = verificationId;
|
|
44
45
|
this.name = "NativeAuthError";
|
|
45
46
|
}
|
|
46
47
|
};
|
|
@@ -138,12 +139,15 @@ var WixNativeAuthEngine = class {
|
|
|
138
139
|
if (payload.twoFAToken && json.success !== true) {
|
|
139
140
|
const current = payload.currentTwoFAMethod ?? "sms";
|
|
140
141
|
const methods = payload.enabledTwoFAMethods ?? [current];
|
|
142
|
+
const id = payload.verificationId;
|
|
143
|
+
const verificationId = (typeof id === "string" || typeof id === "number") && /^\d+$/.test(String(id)) ? String(id) : void 0;
|
|
141
144
|
throw new NativeAuthError(
|
|
142
145
|
"needsTwoFactor",
|
|
143
146
|
"Two-factor verification required.",
|
|
144
147
|
payload.twoFAToken,
|
|
145
148
|
current,
|
|
146
|
-
methods
|
|
149
|
+
methods,
|
|
150
|
+
verificationId
|
|
147
151
|
);
|
|
148
152
|
}
|
|
149
153
|
if (json.success !== true || !payload.guid) {
|
|
@@ -914,10 +918,12 @@ function classifyAuthErrorCode(code) {
|
|
|
914
918
|
var WixAuthModalities = class {
|
|
915
919
|
constructor(config = {}) {
|
|
916
920
|
__publicField(this, "baseURL");
|
|
921
|
+
__publicField(this, "verificationBaseURL");
|
|
917
922
|
__publicField(this, "fetchImpl");
|
|
918
923
|
__publicField(this, "sleep");
|
|
919
924
|
__publicField(this, "devMode");
|
|
920
925
|
this.baseURL = config.baseURL ?? "https://users.wix.com";
|
|
926
|
+
this.verificationBaseURL = config.verificationBaseURL ?? "https://manage.wix.com";
|
|
921
927
|
this.fetchImpl = config.fetchImpl ?? globalThis.fetch;
|
|
922
928
|
this.sleep = config.sleep ?? engineSleep("WixAuthModalities");
|
|
923
929
|
this.devMode = config.devMode ?? false;
|
|
@@ -942,25 +948,60 @@ var WixAuthModalities = class {
|
|
|
942
948
|
return { userId: p.guid ?? "", email: p.email ?? "", accessToken: access, refreshToken: p.wixSession2 ?? "" };
|
|
943
949
|
}
|
|
944
950
|
/** Push-based 2FA: poll for the user's approval on their trusted device. Loops
|
|
945
|
-
* until approved/denied/expired or `maxPolls` is hit.
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
951
|
+
* until approved/denied/expired or `maxPolls` is hit (default 60 × 5s = 5 minutes).
|
|
952
|
+
*
|
|
953
|
+
* #4309 — the wire Wix's own native client uses (mobile-native-core LegacyTwoFactor), and
|
|
954
|
+
* the one the native WixNativeAuthEngine polls: Verification v1 GetChallenge,
|
|
955
|
+
* `GET manage.wix.com/_api/verification-web/v1/challenges/get-challenge?verificationId=…`,
|
|
956
|
+
* keyed by the 2FA payload's `verificationId` (digits; `NativeAuthError.verificationId` on the
|
|
957
|
+
* needsTwoFactor challenge — not its `twoFAToken`). After "approved" the caller completes
|
|
958
|
+
* the login with ONE `/auth/m/verifycodeandlogin` carrying an empty code. The old
|
|
959
|
+
* `/auth/m/push2fa/status` route was never Wix's. */
|
|
960
|
+
async pollPushApproval(verificationId, opts = {}) {
|
|
961
|
+
const interval = opts.intervalMs ?? 5e3;
|
|
962
|
+
const maxPolls = opts.maxPolls ?? 60;
|
|
963
|
+
if (!this.devMode && !/^\d+$/.test(verificationId)) {
|
|
964
|
+
throw new NativeAuthError("unknown", "Push approval isn't available. Choose another method.");
|
|
965
|
+
}
|
|
949
966
|
for (let i = 0; i < maxPolls; i++) {
|
|
950
|
-
const state = await this.pushStatusOnce(
|
|
967
|
+
const state = await this.pushStatusOnce(verificationId, i);
|
|
951
968
|
if (state !== "pending") return state;
|
|
952
969
|
await this.sleep(interval);
|
|
953
970
|
}
|
|
954
971
|
return "expired";
|
|
955
972
|
}
|
|
956
|
-
async pushStatusOnce(
|
|
973
|
+
async pushStatusOnce(verificationId, poll) {
|
|
957
974
|
if (this.devMode) {
|
|
958
|
-
if (
|
|
975
|
+
if (verificationId === "deny") return "denied";
|
|
959
976
|
return poll >= 1 ? "approved" : "pending";
|
|
960
977
|
}
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
978
|
+
let res;
|
|
979
|
+
try {
|
|
980
|
+
res = await this.fetchImpl(
|
|
981
|
+
`${this.verificationBaseURL}/_api/verification-web/v1/challenges/get-challenge?verificationId=${verificationId}`,
|
|
982
|
+
{ method: "GET", headers: { Accept: "application/json" } }
|
|
983
|
+
);
|
|
984
|
+
} catch {
|
|
985
|
+
return "pending";
|
|
986
|
+
}
|
|
987
|
+
if (res.status === 404) return "expired";
|
|
988
|
+
if (!res.ok) return "pending";
|
|
989
|
+
let j = {};
|
|
990
|
+
try {
|
|
991
|
+
j = JSON.parse(await res.text());
|
|
992
|
+
} catch {
|
|
993
|
+
return "pending";
|
|
994
|
+
}
|
|
995
|
+
switch (j.challenge?.approvalChallenge?.status) {
|
|
996
|
+
case "APPROVED":
|
|
997
|
+
return "approved";
|
|
998
|
+
case "DECLINED":
|
|
999
|
+
return "denied";
|
|
1000
|
+
case "EXPIRED":
|
|
1001
|
+
return "expired";
|
|
1002
|
+
default:
|
|
1003
|
+
return "pending";
|
|
1004
|
+
}
|
|
964
1005
|
}
|
|
965
1006
|
/** Device-login: approve a login started on another device (confirm-on-device). */
|
|
966
1007
|
async confirmDeviceLogin(userCode, authToken) {
|
|
@@ -1194,6 +1235,12 @@ function WixAuthProvider(config) {
|
|
|
1194
1235
|
authorizationEndpoint: config.authorizationEndpoint
|
|
1195
1236
|
});
|
|
1196
1237
|
}
|
|
1238
|
+
function googleClientIds(google) {
|
|
1239
|
+
const out = {};
|
|
1240
|
+
if (google?.iosClientId) out.iosClientId = google.iosClientId;
|
|
1241
|
+
if (google?.serverClientId) out.serverClientId = google.serverClientId;
|
|
1242
|
+
return Object.keys(out).length ? out : void 0;
|
|
1243
|
+
}
|
|
1197
1244
|
function WixNativeAuthProvider(config) {
|
|
1198
1245
|
if (config.mode !== "owner" && config.mode !== "consumer" && config.mode !== "account") {
|
|
1199
1246
|
throw new Error('WixNativeAuthProvider: mode must be "owner", "consumer" or "account".');
|
|
@@ -1205,6 +1252,7 @@ function WixNativeAuthProvider(config) {
|
|
|
1205
1252
|
...config.clientId ? { clientId: config.clientId } : {},
|
|
1206
1253
|
...config.redirectUri ? { redirectUri: config.redirectUri } : {},
|
|
1207
1254
|
...config.social ? { social: config.social } : {},
|
|
1255
|
+
...googleClientIds(config.google) ? { google: googleClientIds(config.google) } : {},
|
|
1208
1256
|
...config.apiBase ? { apiBase: config.apiBase } : {},
|
|
1209
1257
|
...config.pxToken ? { pxToken: config.pxToken } : {},
|
|
1210
1258
|
...config.petriOverrides ? { petriOverrides: config.petriOverrides } : {},
|
package/dist/cli.mjs
CHANGED
|
@@ -158566,30 +158566,30 @@ var init_preview_assets_generated = __esm({
|
|
|
158566
158566
|
"../../packages/serve/src/preview-assets.generated.ts"() {
|
|
158567
158567
|
init_preview_assets_format();
|
|
158568
158568
|
PREVIEW_ASSET_MANIFEST = [
|
|
158569
|
-
{ key: "assets/DashboardHost-
|
|
158570
|
-
{ key: "assets/DevDrawer-
|
|
158571
|
-
{ key: "assets/IdiomCompare-
|
|
158572
|
-
{ key: "assets/SchemeCompare-
|
|
158573
|
-
{ key: "assets/index-
|
|
158574
|
-
{ key: "assets/pdf-
|
|
158575
|
-
{ key: "assets/pdf.worker.min-BQa_JDET.js", contentType: "application/javascript; charset=utf-8", offset:
|
|
158576
|
-
{ key: "assets/pdf.worker.min-BmVo14Nb.mjs", contentType: "application/javascript; charset=utf-8", offset:
|
|
158577
|
-
{ key: "assets/pdfDocument-
|
|
158578
|
-
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset:
|
|
158579
|
-
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset:
|
|
158580
|
-
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset:
|
|
158581
|
-
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
158582
|
-
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset:
|
|
158583
|
-
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset:
|
|
158584
|
-
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
158585
|
-
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset:
|
|
158586
|
-
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
158587
|
-
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset:
|
|
158588
|
-
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset:
|
|
158589
|
-
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
158590
|
-
{ key: "himi-sw.js", contentType: "application/javascript; charset=utf-8", offset:
|
|
158591
|
-
{ key: "index.html", contentType: "text/html; charset=utf-8", offset:
|
|
158592
|
-
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset:
|
|
158569
|
+
{ key: "assets/DashboardHost-6DvWku4i.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 2916, sha256: "46e3ab97803e805b234fb086ed27eba4cfc5e930e0b9e8812119ffac987a93b6" },
|
|
158570
|
+
{ key: "assets/DevDrawer-G_2i4pRi.js", contentType: "application/javascript; charset=utf-8", offset: 2924, length: 16744, sha256: "c0f9e787c8d568c6b137a2f3263678d73fb2594aa5ed0bf4ccc114abe0c3b144" },
|
|
158571
|
+
{ key: "assets/IdiomCompare-h8in8vjb.js", contentType: "application/javascript; charset=utf-8", offset: 19668, length: 1892, sha256: "d6a486564253b0e69d9c072534b5fc0b14fd6ee0fa2b96533779c052f374001c" },
|
|
158572
|
+
{ key: "assets/SchemeCompare-3x7S1joY.js", contentType: "application/javascript; charset=utf-8", offset: 21560, length: 1819, sha256: "8a1dbd7789ed364054e51bdbe6ee059b9a0ed7c14d93c7943a259d025e59e685" },
|
|
158573
|
+
{ key: "assets/index-Dk8Fbe24.js", contentType: "application/javascript; charset=utf-8", offset: 23379, length: 1347630, sha256: "c32d9c00c974f661644e7dab457e04320bebcd6048fd3289723b2994f4e3fa6a" },
|
|
158574
|
+
{ key: "assets/pdf-DO5DPR9X.js", contentType: "application/javascript; charset=utf-8", offset: 1371009, length: 488199, sha256: "f82b99f57e8f1bb281f7047ed3294751a27517f488bf55457ba05dc51b468ea1" },
|
|
158575
|
+
{ key: "assets/pdf.worker.min-BQa_JDET.js", contentType: "application/javascript; charset=utf-8", offset: 1859208, length: 73, sha256: "41bcfda4f3c8c0a81c785ea87c69afc8e7d0ed8c333324aee94c273d881bb6aa" },
|
|
158576
|
+
{ key: "assets/pdf.worker.min-BmVo14Nb.mjs", contentType: "application/javascript; charset=utf-8", offset: 1859281, length: 1317034, sha256: "a33cfe728c584fdba4fcc1fd54bcdc2f9f2f13889ddbb5b2bd1d0f8cbe49b84e" },
|
|
158577
|
+
{ key: "assets/pdfDocument-CnBMTr3b.js", contentType: "application/javascript; charset=utf-8", offset: 3176315, length: 2868, sha256: "496494bdb4b29138dc9a588dfe2795abda60a5911f2f84a68dbcdd604097024e" },
|
|
158578
|
+
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 3179183, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
|
|
158579
|
+
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 3183793, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
|
|
158580
|
+
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 3672377, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
|
|
158581
|
+
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 3763301, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
|
|
158582
|
+
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 3854285, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
|
|
158583
|
+
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 3945265, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
|
|
158584
|
+
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 4036137, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
|
|
158585
|
+
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 4127117, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
|
|
158586
|
+
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 4235753, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
|
|
158587
|
+
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 4344837, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
|
|
158588
|
+
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 4453885, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
|
|
158589
|
+
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 4561585, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
|
|
158590
|
+
{ key: "himi-sw.js", contentType: "application/javascript; charset=utf-8", offset: 4649693, length: 6748, sha256: "4a92459977d7cefa1a6a7e020c3a63509737f083b3f2773557c1a5771665811a" },
|
|
158591
|
+
{ key: "index.html", contentType: "text/html; charset=utf-8", offset: 4656441, length: 4947, sha256: "8a3e407eac0cc5028b16d9b6baa12018a35f017e25164e830471a643313d690b" },
|
|
158592
|
+
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 4661388, length: 17768, sha256: "a47dec8623a0f58def7d8785ee74d08483626e75d07c9328bfc9ecb2172c2e0d" }
|
|
158593
158593
|
];
|
|
158594
158594
|
}
|
|
158595
158595
|
});
|
|
Binary file
|
|
@@ -112,6 +112,48 @@ browser-direct to wixapis instead). See `core/web-host/src/App.tsx`. There is no
|
|
|
112
112
|
> **rejects with `sign_in_unavailable`** unless the `__webwix` bridge already holds a member. Catch that and
|
|
113
113
|
> show a real error state — it is the difference between "sign-in isn't available here" and a dead button.
|
|
114
114
|
|
|
115
|
+
## Social sign-in (Google, Apple) and push-approval 2FA
|
|
116
|
+
|
|
117
|
+
`social: ["google", "apple"]` on `WixNativeAuthProvider` lists the buttons the app *may* show. The
|
|
118
|
+
native gate shows only the ones that can actually run on that platform, so a button never fails with
|
|
119
|
+
"This sign-in method isn't available":
|
|
120
|
+
|
|
121
|
+
| Provider | iOS | Android |
|
|
122
|
+
|---|---|---|
|
|
123
|
+
| Apple | always (Sign in with Apple, needs the entitlement) | never (no native path) |
|
|
124
|
+
| Google | when `HimalayaWixAuthGoogle` is linked **and** an iOS client id is configured | when `:himalaya-wix-auth-google` is linked **and** a server client id is configured |
|
|
125
|
+
|
|
126
|
+
Enable Google in four steps:
|
|
127
|
+
|
|
128
|
+
1. Configure the client ids (from a Google Cloud project whose tokens Wix's
|
|
129
|
+
`/oneapp/social/sign-in/google` accepts):
|
|
130
|
+
```ts
|
|
131
|
+
WixNativeAuthProvider({ mode: "owner", social: ["google", "apple"],
|
|
132
|
+
google: { iosClientId: "<ios>.apps.googleusercontent.com", serverClientId: "<web>.apps.googleusercontent.com" } })
|
|
133
|
+
```
|
|
134
|
+
An id left out hides Google on that platform: `iosClientId` for iOS, `serverClientId` (the WEB
|
|
135
|
+
client) for Android.
|
|
136
|
+
2. **iOS** — add the `HimalayaWixAuthGoogle` package to the app (it pulls GoogleSignIn-iOS), add the
|
|
137
|
+
reversed iOS client id as a URL scheme (`CFBundleURLTypes`), and call
|
|
138
|
+
`HimalayaWixAuthGoogle.register(clientId:serverClientId:)` at boot, before the gate's provider list
|
|
139
|
+
is built.
|
|
140
|
+
3. **Android** — include `:himalaya-wix-auth-google` (androidx.credentials + Google identity) and call
|
|
141
|
+
`CredentialManagerGoogleAdapter.register(context, serverClientId)` at boot.
|
|
142
|
+
4. Filter the baked `social` list before handing it to the gate:
|
|
143
|
+
`SocialSignInCoordinator.shared.availableProviders(requested, devMode:)` (iOS) /
|
|
144
|
+
`SocialSignInAdapters.available(requested, devMode)` (Android). The dev seam (`devMode`) shows every
|
|
145
|
+
provider and answers with a dev credential.
|
|
146
|
+
|
|
147
|
+
Only a real cancel reads as "cancelled"; a misconfigured client id surfaces Google's own message.
|
|
148
|
+
|
|
149
|
+
**Push-approval 2FA (owner/account).** When a Wix account's second factor is push approval, the gate
|
|
150
|
+
shows "Approve the sign-in on your other device." instead of a code field and waits on its own: the
|
|
151
|
+
provider polls Wix's Verification API with the challenge's `verificationId` (every 5s, at most 5
|
|
152
|
+
minutes) and, once approved, completes the login with an empty code. Declined and expired requests show
|
|
153
|
+
their own message; the primary button sends a new request, and the method picker switches to a code
|
|
154
|
+
factor at any time. Dev seam accounts: `2fa-push@himalaya.dev` (approves) and
|
|
155
|
+
`2fa-push-deny@himalaya.dev` (declines), password `Passw0rd!`.
|
|
156
|
+
|
|
115
157
|
## Fail-closed (`required: true`)
|
|
116
158
|
|
|
117
159
|
If a required-auth app can't build its provider (unknown `providerId`, missing config key), boot sets a
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1402.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": "52ee343f360b7adc92355c0a381f833835c5bbe5dfe40716324c1ad5"
|
|
75
75
|
}
|