chofex-cli 0.1.147 → 0.1.148
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/index.js +80 -26
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -58828,6 +58828,39 @@ var ChallengeCatalogSchema = exports_Schema.Struct({
|
|
|
58828
58828
|
});
|
|
58829
58829
|
|
|
58830
58830
|
// ../../packages/registration-contract/src/index.ts
|
|
58831
|
+
var campaignAttributionHandoffHeader = "x-chofex-campaign-attribution";
|
|
58832
|
+
var eventUuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
58833
|
+
function campaignAttributionHandoffValue(handoff) {
|
|
58834
|
+
if (!eventUuidPattern.test(handoff.landingId))
|
|
58835
|
+
return;
|
|
58836
|
+
if (!Number.isSafeInteger(handoff.capturedAt) || handoff.capturedAt < 0)
|
|
58837
|
+
return;
|
|
58838
|
+
return `${handoff.landingId}.${handoff.capturedAt}`;
|
|
58839
|
+
}
|
|
58840
|
+
function campaignAttributionHandoffFromValue(value3) {
|
|
58841
|
+
if (!value3)
|
|
58842
|
+
return;
|
|
58843
|
+
const separator = value3.lastIndexOf(".");
|
|
58844
|
+
if (separator < 0)
|
|
58845
|
+
return;
|
|
58846
|
+
const landingId = value3.slice(0, separator);
|
|
58847
|
+
const capturedAt = Number(value3.slice(separator + 1));
|
|
58848
|
+
const handoff = { capturedAt, landingId };
|
|
58849
|
+
if (campaignAttributionHandoffValue(handoff) !== value3)
|
|
58850
|
+
return;
|
|
58851
|
+
return handoff;
|
|
58852
|
+
}
|
|
58853
|
+
function campaignAttributionFromOAuthState(expectedState, returnedState) {
|
|
58854
|
+
if (returnedState === expectedState)
|
|
58855
|
+
return { valid: true };
|
|
58856
|
+
const prefix = `${expectedState}.`;
|
|
58857
|
+
if (!returnedState?.startsWith(prefix))
|
|
58858
|
+
return { valid: false };
|
|
58859
|
+
const handoff = campaignAttributionHandoffFromValue(returnedState.slice(prefix.length));
|
|
58860
|
+
if (!handoff)
|
|
58861
|
+
return { valid: false };
|
|
58862
|
+
return { valid: true, handoff };
|
|
58863
|
+
}
|
|
58831
58864
|
var nonBlank = (maximum) => exports_Schema.Trim.pipe(exports_Schema.check(exports_Schema.isMinLength(1), exports_Schema.isMaxLength(maximum)));
|
|
58832
58865
|
var optionalText = (maximum) => exports_Schema.optional(nonBlank(maximum));
|
|
58833
58866
|
var nullableOptionalText = (maximum) => exports_Schema.optional(exports_Schema.NullOr(nonBlank(maximum)));
|
|
@@ -59140,11 +59173,13 @@ import { createServer } from "node:http";
|
|
|
59140
59173
|
|
|
59141
59174
|
// src/config.ts
|
|
59142
59175
|
var oauthIssuer = process.env.CHOFEX_OAUTH_ISSUER ?? "https://clerk.hacktheandes.com";
|
|
59176
|
+
var publicSiteUrl = process.env.CHOFEX_PUBLIC_SITE_URL ?? "https://hacktheandes.com";
|
|
59143
59177
|
var config = {
|
|
59144
59178
|
apiUrl: process.env.CHOFEX_API_URL ?? "https://hacktheandes.com",
|
|
59145
|
-
publicSiteUrl
|
|
59179
|
+
publicSiteUrl,
|
|
59146
59180
|
oauthClientId: process.env.CHOFEX_OAUTH_CLIENT_ID ?? "HddO78wKpq5PFIEl",
|
|
59147
59181
|
authorizationUrl: `${oauthIssuer}/oauth/authorize`,
|
|
59182
|
+
authorizationBridgeUrl: `${publicSiteUrl}/api/v1/oauth/authorize`,
|
|
59148
59183
|
tokenUrl: `${oauthIssuer}/oauth/token`,
|
|
59149
59184
|
revocationUrl: `${oauthIssuer}/oauth/token/revoke`
|
|
59150
59185
|
};
|
|
@@ -59304,7 +59339,7 @@ var tokenEndpointError = (status, body) => {
|
|
|
59304
59339
|
const detail = description ? `: ${description}` : "";
|
|
59305
59340
|
return new Error(`Clerk OAuth token endpoint returned ${status}${detail}`);
|
|
59306
59341
|
};
|
|
59307
|
-
var credentialsFromToken = (body, previousRefreshToken) => {
|
|
59342
|
+
var credentialsFromToken = (body, previousRefreshToken, campaignAttribution) => {
|
|
59308
59343
|
if (typeof body.access_token !== "string") {
|
|
59309
59344
|
let detail = "";
|
|
59310
59345
|
if (typeof body.error_description === "string") {
|
|
@@ -59322,6 +59357,7 @@ var credentialsFromToken = (body, previousRefreshToken) => {
|
|
|
59322
59357
|
}
|
|
59323
59358
|
return {
|
|
59324
59359
|
accessToken: body.access_token,
|
|
59360
|
+
campaignAttribution,
|
|
59325
59361
|
refreshToken,
|
|
59326
59362
|
expiresAt
|
|
59327
59363
|
};
|
|
@@ -59360,20 +59396,26 @@ var refresh = async (credentials) => {
|
|
|
59360
59396
|
refresh_token: credentials.refreshToken,
|
|
59361
59397
|
client_id: config.oauthClientId
|
|
59362
59398
|
});
|
|
59363
|
-
const updated = credentialsFromToken(body, credentials.refreshToken);
|
|
59399
|
+
const updated = credentialsFromToken(body, credentials.refreshToken, credentials.campaignAttribution);
|
|
59364
59400
|
await saveCredentials(updated);
|
|
59365
59401
|
return updated;
|
|
59366
59402
|
};
|
|
59367
|
-
var
|
|
59368
|
-
if (process.env.CHOFEX_TOKEN)
|
|
59369
|
-
return process.env.CHOFEX_TOKEN;
|
|
59403
|
+
var authentication = async (forceRefresh = false) => {
|
|
59404
|
+
if (process.env.CHOFEX_TOKEN) {
|
|
59405
|
+
return { accessToken: process.env.CHOFEX_TOKEN };
|
|
59406
|
+
}
|
|
59370
59407
|
const credentials = await readCredentials();
|
|
59371
59408
|
if (!credentials)
|
|
59372
59409
|
throw new Error("Not logged in. Run `chofex login`.");
|
|
59373
59410
|
if (forceRefresh || credentials.expiresAt !== undefined && credentials.expiresAt <= Date.now() + 30000) {
|
|
59374
|
-
return
|
|
59411
|
+
return await refresh(credentials);
|
|
59375
59412
|
}
|
|
59376
|
-
return credentials
|
|
59413
|
+
return credentials;
|
|
59414
|
+
};
|
|
59415
|
+
var bridgedAuthorizationUrl = (bridgeUrl, authorizationUrl) => {
|
|
59416
|
+
const bridge = new URL(bridgeUrl);
|
|
59417
|
+
bridge.search = new URL(authorizationUrl).search;
|
|
59418
|
+
return bridge.toString();
|
|
59377
59419
|
};
|
|
59378
59420
|
var browserCommand = (url2, platform = process.platform) => {
|
|
59379
59421
|
if (platform === "darwin")
|
|
@@ -59412,7 +59454,8 @@ var login = async () => {
|
|
|
59412
59454
|
}
|
|
59413
59455
|
const error2 = url2.searchParams.get("error");
|
|
59414
59456
|
const authorizationCode = url2.searchParams.get("code");
|
|
59415
|
-
|
|
59457
|
+
const attributionState = campaignAttributionFromOAuthState(state, url2.searchParams.get("state"));
|
|
59458
|
+
if (!attributionState.valid || error2 || !authorizationCode) {
|
|
59416
59459
|
response.writeHead(400, { "content-type": "text/plain" }).end("Chofex login failed. You can close this window.");
|
|
59417
59460
|
let message = "Invalid OAuth callback";
|
|
59418
59461
|
if (error2)
|
|
@@ -59421,7 +59464,10 @@ var login = async () => {
|
|
|
59421
59464
|
return;
|
|
59422
59465
|
}
|
|
59423
59466
|
response.writeHead(200, { "content-type": "text/plain" }).end("Chofex login complete. You can close this window.");
|
|
59424
|
-
finish(
|
|
59467
|
+
finish({
|
|
59468
|
+
authorizationCode,
|
|
59469
|
+
campaignAttribution: attributionState.handoff
|
|
59470
|
+
});
|
|
59425
59471
|
});
|
|
59426
59472
|
await new Promise((resolve4, reject) => {
|
|
59427
59473
|
server.once("error", reject);
|
|
@@ -59448,23 +59494,24 @@ var login = async () => {
|
|
|
59448
59494
|
server.close();
|
|
59449
59495
|
throw error2;
|
|
59450
59496
|
}
|
|
59497
|
+
const browserUrl = bridgedAuthorizationUrl(config.authorizationBridgeUrl, authorizationUrl.toString());
|
|
59451
59498
|
console.error(`Sign in here (waiting up to five minutes):
|
|
59452
59499
|
|
|
59453
|
-
${
|
|
59500
|
+
${browserUrl}
|
|
59454
59501
|
|
|
59455
59502
|
If the browser did not open automatically, open that URL yourself.`);
|
|
59456
|
-
openBrowser(
|
|
59503
|
+
openBrowser(browserUrl);
|
|
59457
59504
|
const timeout3 = setTimeout(() => fail11(new Error("Login timed out after five minutes")), 300000);
|
|
59458
59505
|
try {
|
|
59459
|
-
const
|
|
59506
|
+
const callback4 = await code;
|
|
59460
59507
|
const body = await tokenRequest({
|
|
59461
59508
|
grant_type: "authorization_code",
|
|
59462
59509
|
client_id: config.oauthClientId,
|
|
59463
|
-
code: authorizationCode,
|
|
59510
|
+
code: callback4.authorizationCode,
|
|
59464
59511
|
redirect_uri: redirectUri,
|
|
59465
59512
|
code_verifier: verifier
|
|
59466
59513
|
});
|
|
59467
|
-
const credentials = credentialsFromToken(body);
|
|
59514
|
+
const credentials = credentialsFromToken(body, undefined, callback4.campaignAttribution);
|
|
59468
59515
|
await saveCredentials(credentials);
|
|
59469
59516
|
return credentials.accessToken;
|
|
59470
59517
|
} finally {
|
|
@@ -59537,20 +59584,27 @@ var exitCodeFor = (error2) => {
|
|
|
59537
59584
|
|
|
59538
59585
|
// src/api-client.ts
|
|
59539
59586
|
var endpoint = (apiUrl, path4) => `${apiUrl.replace(/\/$/, "")}${path4}`;
|
|
59540
|
-
var
|
|
59541
|
-
if (suppliedToken)
|
|
59542
|
-
return exports_Effect.succeed(suppliedToken);
|
|
59587
|
+
var resolveAuthentication = (suppliedToken, campaignAttribution, forceRefresh = false) => {
|
|
59588
|
+
if (suppliedToken) {
|
|
59589
|
+
return exports_Effect.succeed({ accessToken: suppliedToken, campaignAttribution });
|
|
59590
|
+
}
|
|
59543
59591
|
return exports_Effect.tryPromise({
|
|
59544
|
-
try: () =>
|
|
59592
|
+
try: () => authentication(forceRefresh),
|
|
59545
59593
|
catch: (error2) => cliError("AUTHENTICATION_REQUIRED", String(error2), false)
|
|
59546
59594
|
});
|
|
59547
59595
|
};
|
|
59548
|
-
var sendRequest = (options, path4, init,
|
|
59596
|
+
var sendRequest = (options, path4, init, credentials) => exports_Effect.tryPromise({
|
|
59549
59597
|
try: () => {
|
|
59550
59598
|
const headers = new Headers(init.headers);
|
|
59551
59599
|
headers.set("accept", "application/json");
|
|
59552
|
-
if (
|
|
59553
|
-
headers.set("authorization", `Bearer ${
|
|
59600
|
+
if (credentials) {
|
|
59601
|
+
headers.set("authorization", `Bearer ${credentials.accessToken}`);
|
|
59602
|
+
if (credentials.campaignAttribution) {
|
|
59603
|
+
const handoff = campaignAttributionHandoffValue(credentials.campaignAttribution);
|
|
59604
|
+
if (handoff)
|
|
59605
|
+
headers.set(campaignAttributionHandoffHeader, handoff);
|
|
59606
|
+
}
|
|
59607
|
+
}
|
|
59554
59608
|
headers.set("x-request-id", crypto.randomUUID());
|
|
59555
59609
|
if (init.body !== undefined) {
|
|
59556
59610
|
headers.set("content-type", "application/json");
|
|
@@ -59579,11 +59633,11 @@ var decodeHttpBody = exports_Effect.fn("decodeHttpBody")(function* (response, de
|
|
|
59579
59633
|
});
|
|
59580
59634
|
var request3 = exports_Effect.fn("apiRequest")(function* (options, path4, init, decodeResponse) {
|
|
59581
59635
|
const suppliedToken = options.token ?? process.env.CHOFEX_TOKEN;
|
|
59582
|
-
let
|
|
59583
|
-
let response = yield* sendRequest(options, path4, init,
|
|
59636
|
+
let credentials = yield* resolveAuthentication(suppliedToken, options.campaignAttribution);
|
|
59637
|
+
let response = yield* sendRequest(options, path4, init, credentials);
|
|
59584
59638
|
if (response.status === 401 && !suppliedToken) {
|
|
59585
|
-
|
|
59586
|
-
response = yield* sendRequest(options, path4, init,
|
|
59639
|
+
credentials = yield* resolveAuthentication(undefined, undefined, true);
|
|
59640
|
+
response = yield* sendRequest(options, path4, init, credentials);
|
|
59587
59641
|
}
|
|
59588
59642
|
return yield* decodeHttpBody(response, decodeResponse);
|
|
59589
59643
|
});
|