@jskit-ai/jskit-cli 0.2.142 → 0.2.144
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/jskit-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.144",
|
|
4
4
|
"description": "Bundle and package orchestration CLI for JSKIT apps.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"test": "node --test"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@jskit-ai/jskit-catalog": "0.1.
|
|
24
|
+
"@jskit-ai/jskit-catalog": "0.1.138",
|
|
25
25
|
"@jskit-ai/kernel": "0.1.124",
|
|
26
26
|
"@jskit-ai/shell-web": "0.1.125",
|
|
27
27
|
"@vue/compiler-sfc": "^3.5.29",
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
} from "./appCommandCatalog.js";
|
|
11
11
|
import { runAppAdoptManagedScriptsCommand } from "./appCommands/adoptManagedScripts.js";
|
|
12
12
|
import { runAppMigrateSourceMutationsCommand } from "./appCommands/migrateSourceMutations.js";
|
|
13
|
+
import { runAppPreviewIdentityCommand } from "./appCommands/previewIdentity.js";
|
|
13
14
|
import { runAppReleaseCommand } from "./appCommands/release.js";
|
|
14
15
|
import { runAppSyncCiCommand } from "./appCommands/syncCi.js";
|
|
15
16
|
import { runAppUpdatePackagesCommand } from "./appCommands/updatePackages.js";
|
|
@@ -83,7 +84,7 @@ function createAppCommands(ctx = {}) {
|
|
|
83
84
|
resolveAppRootFromCwd
|
|
84
85
|
} = ctx;
|
|
85
86
|
|
|
86
|
-
async function commandApp({ positional = [], options = {}, cwd = "", stdout, stderr }) {
|
|
87
|
+
async function commandApp({ positional = [], options = {}, cwd = "", stdout, stderr, io = {} }) {
|
|
87
88
|
const appRoot = await resolveAppRootFromCwd(cwd);
|
|
88
89
|
const firstToken = String(positional[0] || "").trim();
|
|
89
90
|
const secondToken = String(positional[1] || "").trim();
|
|
@@ -137,6 +138,12 @@ function createAppCommands(ctx = {}) {
|
|
|
137
138
|
if (definition.name === "verify") {
|
|
138
139
|
return runAppVerifyCommand(ctx, { appRoot, options, stdout, stderr });
|
|
139
140
|
}
|
|
141
|
+
if (definition.name === "preview-identity") {
|
|
142
|
+
return runAppPreviewIdentityCommand(ctx, {
|
|
143
|
+
stdin: io.stdin,
|
|
144
|
+
stdout
|
|
145
|
+
});
|
|
146
|
+
}
|
|
140
147
|
if (definition.name === "verify-ui") {
|
|
141
148
|
return runAppVerifyUiCommand(ctx, { appRoot, options, stdout, stderr });
|
|
142
149
|
}
|
|
@@ -22,6 +22,17 @@ const COPIED_APP_SCRIPT_FILES = Object.freeze([
|
|
|
22
22
|
]);
|
|
23
23
|
|
|
24
24
|
const APP_COMMAND_DEFINITIONS = Object.freeze({
|
|
25
|
+
"preview-identity": Object.freeze({
|
|
26
|
+
name: "preview-identity",
|
|
27
|
+
summary: "Run the app-owned Vibe64 preview-identity command protocol.",
|
|
28
|
+
usage: "jskit app preview-identity",
|
|
29
|
+
options: Object.freeze([]),
|
|
30
|
+
defaults: Object.freeze([
|
|
31
|
+
"Reads one versioned preview-identity request from stdin and writes one JSON response to stdout.",
|
|
32
|
+
"Uses the running local JSKIT app to create a native session for an existing user only.",
|
|
33
|
+
"This machine command is enabled only by the managed development-preview environment."
|
|
34
|
+
])
|
|
35
|
+
}),
|
|
25
36
|
verify: Object.freeze({
|
|
26
37
|
name: "verify",
|
|
27
38
|
summary: "Run the JSKIT baseline app verification flow.",
|
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
const PREVIEW_IDENTITY_PROTOCOL = "vibe64.preview-identity.command.v1";
|
|
2
|
+
const PREVIEW_IDENTITY_LOGIN_OPERATION = "login-as";
|
|
3
|
+
const PREVIEW_IDENTITY_LOGOUT_OPERATION = "logout";
|
|
4
|
+
const PREVIEW_IDENTITY_INPUT_LIMIT_BYTES = 64 * 1024;
|
|
5
|
+
const PREVIEW_IDENTITY_RESPONSE_LIMIT_BYTES = 64 * 1024;
|
|
6
|
+
const PREVIEW_IDENTITY_ENABLED_ENV = "VIBE64_PREVIEW_IDENTITY_ENABLED";
|
|
7
|
+
const PREVIEW_IDENTITY_SECRET_ENV = "VIBE64_PREVIEW_IDENTITY_SECRET";
|
|
8
|
+
const DEV_AUTH_SECRET_HEADER = "x-jskit-dev-auth-secret";
|
|
9
|
+
const AUTH_PATHS = Object.freeze({
|
|
10
|
+
devLoginAs: "/api/dev-auth/login-as",
|
|
11
|
+
logout: "/api/logout",
|
|
12
|
+
session: "/api/session"
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
function previewIdentityResponse(requestId = "", values = {}) {
|
|
16
|
+
return {
|
|
17
|
+
protocol: PREVIEW_IDENTITY_PROTOCOL,
|
|
18
|
+
requestId: String(requestId || ""),
|
|
19
|
+
...values
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function previewIdentityFailure(requestId = "", error = {}) {
|
|
24
|
+
return previewIdentityResponse(requestId, {
|
|
25
|
+
code: String(error.code || "jskit_preview_identity_failed"),
|
|
26
|
+
error: String(error.message || error || "JSKIT preview identity failed."),
|
|
27
|
+
ok: false,
|
|
28
|
+
setCookie: Array.isArray(error.setCookie) ? error.setCookie : [],
|
|
29
|
+
signedOut: error.signedOut === true,
|
|
30
|
+
statusCode: Number.isInteger(Number(error.statusCode)) ? Number(error.statusCode) : 400
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function commandError(message = "", code = "jskit_preview_identity_failed", extra = {}) {
|
|
35
|
+
const error = new Error(message || "JSKIT preview identity failed.");
|
|
36
|
+
error.code = code;
|
|
37
|
+
Object.assign(error, extra);
|
|
38
|
+
return error;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function readInput(stream) {
|
|
42
|
+
let bytes = 0;
|
|
43
|
+
const chunks = [];
|
|
44
|
+
for await (const chunk of stream) {
|
|
45
|
+
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
46
|
+
bytes += buffer.length;
|
|
47
|
+
if (bytes > PREVIEW_IDENTITY_INPUT_LIMIT_BYTES) {
|
|
48
|
+
throw commandError(
|
|
49
|
+
"Preview identity request is too large.",
|
|
50
|
+
"jskit_preview_identity_request_too_large",
|
|
51
|
+
{ statusCode: 413 }
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
chunks.push(buffer);
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
return JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
58
|
+
} catch {
|
|
59
|
+
throw commandError(
|
|
60
|
+
"Preview identity request is invalid JSON.",
|
|
61
|
+
"jskit_preview_identity_request_invalid"
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function normalizeRequest(value = {}) {
|
|
67
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
68
|
+
throw commandError(
|
|
69
|
+
"Preview identity request must be an object.",
|
|
70
|
+
"jskit_preview_identity_request_invalid"
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
const requestId = String(value.requestId || "").trim();
|
|
74
|
+
const operation = String(value.operation || "").trim();
|
|
75
|
+
if (value.protocol !== PREVIEW_IDENTITY_PROTOCOL || !requestId) {
|
|
76
|
+
throw commandError(
|
|
77
|
+
"Preview identity request protocol is invalid.",
|
|
78
|
+
"jskit_preview_identity_protocol_invalid"
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
if (![PREVIEW_IDENTITY_LOGIN_OPERATION, PREVIEW_IDENTITY_LOGOUT_OPERATION].includes(operation)) {
|
|
82
|
+
throw commandError(
|
|
83
|
+
"Preview identity operation is invalid.",
|
|
84
|
+
"jskit_preview_identity_operation_invalid"
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
let target;
|
|
88
|
+
try {
|
|
89
|
+
target = new URL(String(value.target?.origin || value.target?.href || ""));
|
|
90
|
+
} catch {
|
|
91
|
+
throw commandError(
|
|
92
|
+
"Preview identity target must be a local JSKIT application.",
|
|
93
|
+
"jskit_preview_identity_target_invalid"
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
const hostname = target.hostname.toLowerCase().replace(/^\[|\]$/gu, "");
|
|
97
|
+
if (
|
|
98
|
+
target.protocol !== "http:" ||
|
|
99
|
+
!(
|
|
100
|
+
hostname === "localhost" ||
|
|
101
|
+
hostname.endsWith(".localhost") ||
|
|
102
|
+
/^127(?:\.\d{1,3}){3}$/u.test(hostname) ||
|
|
103
|
+
hostname === "::1" ||
|
|
104
|
+
/^vibe64-launch-[a-f0-9]{12}$/u.test(hostname)
|
|
105
|
+
)
|
|
106
|
+
) {
|
|
107
|
+
throw commandError(
|
|
108
|
+
"Preview identity target must be a local JSKIT application.",
|
|
109
|
+
"jskit_preview_identity_target_invalid"
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
operation,
|
|
114
|
+
requestId,
|
|
115
|
+
subject: value.subject,
|
|
116
|
+
targetOrigin: target.origin
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function identityFromSubject(subject = {}) {
|
|
121
|
+
const source = subject && typeof subject === "object" && !Array.isArray(subject) ? subject : {};
|
|
122
|
+
if (source.kind === "selector") {
|
|
123
|
+
const type = String(source.selector?.type || "").trim();
|
|
124
|
+
const value = String(source.selector?.value || "").trim();
|
|
125
|
+
if (type === "email" && value) {
|
|
126
|
+
return { email: value };
|
|
127
|
+
}
|
|
128
|
+
if (type === "user-id" && value) {
|
|
129
|
+
return { userId: value };
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (source.kind === "viewer") {
|
|
133
|
+
const email = (Array.isArray(source.identifiers) ? source.identifiers : [])
|
|
134
|
+
.find((identifier) => identifier?.type === "email" && String(identifier.value || "").trim());
|
|
135
|
+
if (email) {
|
|
136
|
+
return { email: String(email.value).trim() };
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
throw commandError(
|
|
140
|
+
"JSKIT preview identity requires an existing application email or user ID.",
|
|
141
|
+
"jskit_preview_identity_selector_unsupported"
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function responseSetCookie(response = {}) {
|
|
146
|
+
if (typeof response.headers?.getSetCookie === "function") {
|
|
147
|
+
return response.headers.getSetCookie().map(String).filter(Boolean);
|
|
148
|
+
}
|
|
149
|
+
const value = String(response.headers?.get?.("set-cookie") || "").trim();
|
|
150
|
+
return value ? [value] : [];
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function cookieHeader(setCookie = []) {
|
|
154
|
+
const cookies = new Map();
|
|
155
|
+
for (const entry of Array.isArray(setCookie) ? setCookie : []) {
|
|
156
|
+
const pair = String(entry || "").split(";", 1)[0].trim();
|
|
157
|
+
const separatorIndex = pair.indexOf("=");
|
|
158
|
+
const name = separatorIndex > 0 ? pair.slice(0, separatorIndex).trim() : "";
|
|
159
|
+
if (name) {
|
|
160
|
+
cookies.set(name, pair);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return [...cookies.values()].join("; ");
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async function responsePayload(response = {}) {
|
|
167
|
+
const reader = response.body?.getReader?.();
|
|
168
|
+
let text = "";
|
|
169
|
+
if (reader) {
|
|
170
|
+
const decoder = new TextDecoder();
|
|
171
|
+
let bytes = 0;
|
|
172
|
+
while (true) {
|
|
173
|
+
const { done, value } = await reader.read();
|
|
174
|
+
if (done) {
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
bytes += value.byteLength;
|
|
178
|
+
if (bytes > PREVIEW_IDENTITY_RESPONSE_LIMIT_BYTES) {
|
|
179
|
+
await reader.cancel();
|
|
180
|
+
throw commandError(
|
|
181
|
+
"JSKIT preview identity response is too large.",
|
|
182
|
+
"jskit_preview_identity_response_too_large",
|
|
183
|
+
{ statusCode: 502 }
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
text += decoder.decode(value, { stream: true });
|
|
187
|
+
}
|
|
188
|
+
text += decoder.decode();
|
|
189
|
+
} else {
|
|
190
|
+
text = await response.text();
|
|
191
|
+
if (Buffer.byteLength(text) > PREVIEW_IDENTITY_RESPONSE_LIMIT_BYTES) {
|
|
192
|
+
throw commandError(
|
|
193
|
+
"JSKIT preview identity response is too large.",
|
|
194
|
+
"jskit_preview_identity_response_too_large",
|
|
195
|
+
{ statusCode: 502 }
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (!text) {
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
try {
|
|
203
|
+
const payload = JSON.parse(text);
|
|
204
|
+
return payload && typeof payload === "object" && !Array.isArray(payload)
|
|
205
|
+
? payload
|
|
206
|
+
: null;
|
|
207
|
+
} catch {
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function upstreamError(payload = {}, response = {}, extra = {}) {
|
|
213
|
+
const fieldErrors = payload?.details?.fieldErrors || payload?.fieldErrors || {};
|
|
214
|
+
const fieldMessage = Object.values(
|
|
215
|
+
fieldErrors && typeof fieldErrors === "object" && !Array.isArray(fieldErrors) ? fieldErrors : {}
|
|
216
|
+
).find(Boolean);
|
|
217
|
+
const firstError = Array.isArray(payload?.errors) ? payload.errors.find(Boolean) : null;
|
|
218
|
+
return commandError(
|
|
219
|
+
String(
|
|
220
|
+
fieldMessage ||
|
|
221
|
+
firstError?.message ||
|
|
222
|
+
firstError ||
|
|
223
|
+
payload?.error ||
|
|
224
|
+
payload?.message ||
|
|
225
|
+
"JSKIT preview identity exchange failed."
|
|
226
|
+
),
|
|
227
|
+
String(firstError?.code || payload?.code || "jskit_preview_identity_upstream_rejected"),
|
|
228
|
+
{
|
|
229
|
+
...extra,
|
|
230
|
+
statusCode: Number(response.status || 502)
|
|
231
|
+
}
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
async function request(fetchImpl, href, options) {
|
|
236
|
+
try {
|
|
237
|
+
return await fetchImpl(href, options);
|
|
238
|
+
} catch {
|
|
239
|
+
throw commandError(
|
|
240
|
+
"JSKIT preview identity could not reach the application.",
|
|
241
|
+
"jskit_preview_identity_unreachable",
|
|
242
|
+
{ statusCode: 502 }
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function postJson(fetchImpl, href, body, headers = {}) {
|
|
248
|
+
return request(fetchImpl, href, {
|
|
249
|
+
body: JSON.stringify(body),
|
|
250
|
+
headers: {
|
|
251
|
+
"content-type": "application/json",
|
|
252
|
+
...headers
|
|
253
|
+
},
|
|
254
|
+
method: "POST",
|
|
255
|
+
redirect: "manual"
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
async function readSession(fetchImpl, targetOrigin) {
|
|
260
|
+
const response = await request(fetchImpl, `${targetOrigin}${AUTH_PATHS.session}`, {
|
|
261
|
+
method: "GET",
|
|
262
|
+
redirect: "manual"
|
|
263
|
+
});
|
|
264
|
+
const payload = await responsePayload(response);
|
|
265
|
+
const responseCookies = responseSetCookie(response);
|
|
266
|
+
if (!response.ok) {
|
|
267
|
+
throw upstreamError(payload, response, {
|
|
268
|
+
setCookie: responseCookies,
|
|
269
|
+
signedOut: false
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
const csrfToken = String(payload?.csrfToken || "").trim();
|
|
273
|
+
if (!csrfToken) {
|
|
274
|
+
throw commandError(
|
|
275
|
+
"JSKIT session bootstrap did not return a CSRF token.",
|
|
276
|
+
"jskit_preview_identity_csrf_missing",
|
|
277
|
+
{
|
|
278
|
+
setCookie: responseCookies,
|
|
279
|
+
statusCode: 502
|
|
280
|
+
}
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
return {
|
|
284
|
+
csrfToken,
|
|
285
|
+
setCookie: responseCookies
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
async function logout(fetchImpl, targetOrigin, session) {
|
|
290
|
+
const response = await postJson(fetchImpl, `${targetOrigin}${AUTH_PATHS.logout}`, {}, {
|
|
291
|
+
cookie: cookieHeader(session.setCookie),
|
|
292
|
+
"csrf-token": session.csrfToken
|
|
293
|
+
});
|
|
294
|
+
const payload = await responsePayload(response);
|
|
295
|
+
const setCookie = [...session.setCookie, ...responseSetCookie(response)];
|
|
296
|
+
if (!response.ok || payload?.ok !== true) {
|
|
297
|
+
throw upstreamError(payload, response, {
|
|
298
|
+
setCookie,
|
|
299
|
+
signedOut: false
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
return {
|
|
303
|
+
csrfToken: session.csrfToken,
|
|
304
|
+
setCookie
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
async function login(fetchImpl, targetOrigin, identity, secret, session) {
|
|
309
|
+
const loginResponse = await postJson(fetchImpl, `${targetOrigin}${AUTH_PATHS.devLoginAs}`, identity, {
|
|
310
|
+
cookie: cookieHeader(session.setCookie),
|
|
311
|
+
"csrf-token": session.csrfToken,
|
|
312
|
+
[DEV_AUTH_SECRET_HEADER]: secret
|
|
313
|
+
});
|
|
314
|
+
const loginPayload = await responsePayload(loginResponse);
|
|
315
|
+
const loginSetCookie = responseSetCookie(loginResponse);
|
|
316
|
+
const setCookie = [...session.setCookie, ...loginSetCookie];
|
|
317
|
+
if (!loginResponse.ok || loginPayload?.ok !== true) {
|
|
318
|
+
throw upstreamError(loginPayload, loginResponse, {
|
|
319
|
+
setCookie,
|
|
320
|
+
signedOut: true
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
return {
|
|
324
|
+
identity: {
|
|
325
|
+
displayName: String(loginPayload.displayName || loginPayload.username || "").trim(),
|
|
326
|
+
email: String(loginPayload.email || identity.email || "").trim().toLowerCase(),
|
|
327
|
+
userId: String(loginPayload.userId || identity.userId || "").trim(),
|
|
328
|
+
username: String(loginPayload.username || "").trim()
|
|
329
|
+
},
|
|
330
|
+
setCookie
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
async function executeJskitPreviewIdentityRequest(value = {}, {
|
|
335
|
+
env = process.env,
|
|
336
|
+
fetchImpl = globalThis.fetch
|
|
337
|
+
} = {}) {
|
|
338
|
+
let requestId = String(value?.requestId || "").trim();
|
|
339
|
+
try {
|
|
340
|
+
const request = normalizeRequest(value);
|
|
341
|
+
requestId = request.requestId;
|
|
342
|
+
if (typeof fetchImpl !== "function") {
|
|
343
|
+
throw commandError(
|
|
344
|
+
"JSKIT preview identity requires fetch support.",
|
|
345
|
+
"jskit_preview_identity_fetch_unavailable",
|
|
346
|
+
{ statusCode: 500 }
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
if (String(env[PREVIEW_IDENTITY_ENABLED_ENV] || "").trim().toLowerCase() !== "true") {
|
|
350
|
+
throw commandError(
|
|
351
|
+
"JSKIT development identity exchange is not enabled.",
|
|
352
|
+
"jskit_preview_identity_disabled",
|
|
353
|
+
{ statusCode: 403 }
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
const secret = String(env[PREVIEW_IDENTITY_SECRET_ENV] || "").trim();
|
|
357
|
+
if (!/^[a-f0-9]{64}$/u.test(secret)) {
|
|
358
|
+
throw commandError(
|
|
359
|
+
"JSKIT development identity exchange secret is unavailable.",
|
|
360
|
+
"jskit_preview_identity_secret_missing",
|
|
361
|
+
{ statusCode: 500 }
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
const identity = request.operation === PREVIEW_IDENTITY_LOGIN_OPERATION
|
|
365
|
+
? identityFromSubject(request.subject)
|
|
366
|
+
: null;
|
|
367
|
+
const session = await readSession(fetchImpl, request.targetOrigin);
|
|
368
|
+
const signedOutSession = await logout(fetchImpl, request.targetOrigin, session);
|
|
369
|
+
if (request.operation === PREVIEW_IDENTITY_LOGOUT_OPERATION) {
|
|
370
|
+
return previewIdentityResponse(requestId, {
|
|
371
|
+
identity: null,
|
|
372
|
+
ok: true,
|
|
373
|
+
setCookie: signedOutSession.setCookie,
|
|
374
|
+
signedOut: true
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
const result = await login(
|
|
378
|
+
fetchImpl,
|
|
379
|
+
request.targetOrigin,
|
|
380
|
+
identity,
|
|
381
|
+
secret,
|
|
382
|
+
signedOutSession
|
|
383
|
+
);
|
|
384
|
+
return previewIdentityResponse(requestId, {
|
|
385
|
+
identity: result.identity,
|
|
386
|
+
ok: true,
|
|
387
|
+
setCookie: result.setCookie,
|
|
388
|
+
signedOut: false
|
|
389
|
+
});
|
|
390
|
+
} catch (error) {
|
|
391
|
+
return previewIdentityFailure(requestId, error);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
async function runAppPreviewIdentityCommand(_ctx = {}, {
|
|
396
|
+
env = process.env,
|
|
397
|
+
fetchImpl = globalThis.fetch,
|
|
398
|
+
stdin = process.stdin,
|
|
399
|
+
stdout = process.stdout
|
|
400
|
+
} = {}) {
|
|
401
|
+
let request;
|
|
402
|
+
try {
|
|
403
|
+
request = await readInput(stdin);
|
|
404
|
+
} catch (error) {
|
|
405
|
+
stdout.write(`${JSON.stringify(previewIdentityFailure("", error))}\n`);
|
|
406
|
+
return 0;
|
|
407
|
+
}
|
|
408
|
+
const response = await executeJskitPreviewIdentityRequest(request, {
|
|
409
|
+
env,
|
|
410
|
+
fetchImpl
|
|
411
|
+
});
|
|
412
|
+
stdout.write(`${JSON.stringify(response)}\n`);
|
|
413
|
+
return 0;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
export {
|
|
417
|
+
PREVIEW_IDENTITY_PROTOCOL,
|
|
418
|
+
executeJskitPreviewIdentityRequest,
|
|
419
|
+
runAppPreviewIdentityCommand
|
|
420
|
+
};
|
package/src/test/playwright.js
CHANGED
|
@@ -13,7 +13,7 @@ function normalizeBaseUrl(value) {
|
|
|
13
13
|
function createJskitPlaywrightConfig({ env = process.env } = {}) {
|
|
14
14
|
const managedBaseUrl = normalizeBaseUrl(env.PLAYWRIGHT_BASE_URL);
|
|
15
15
|
const baseURL = managedBaseUrl || DEFAULT_LOCAL_BASE_URL;
|
|
16
|
-
const storageState = String(env.
|
|
16
|
+
const storageState = String(env.VIBE64_PLAYWRIGHT_STORAGE_STATE || "").trim();
|
|
17
17
|
|
|
18
18
|
return {
|
|
19
19
|
testDir: "./tests/e2e",
|