kalvium-worklog 1.4.0 → 1.4.1
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/discover-position.d.ts +4 -2
- package/dist/discover-position.js +65 -17
- package/package.json +1 -1
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Discover the user's internship position ID
|
|
3
|
-
* Tries
|
|
2
|
+
* Discover the user's internship position ID.
|
|
3
|
+
* Tries JWT extraction first (no browser needed).
|
|
4
|
+
* Falls back to browser-based discovery via Playwright if available.
|
|
5
|
+
* On Android, uses JWT extraction only.
|
|
4
6
|
*/
|
|
5
7
|
export declare function discoverPosition(): Promise<boolean>;
|
|
@@ -1,31 +1,71 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { PROFILE_DIR, CONFIG_FILE, ensureInstallDir, saveConfig, } from "./config.js";
|
|
1
|
+
import { PROFILE_DIR, CONFIG_FILE, ensureInstallDir, saveConfig, loadToken, getPositionIdFromToken, } from "./config.js";
|
|
3
2
|
/**
|
|
4
|
-
*
|
|
5
|
-
|
|
3
|
+
* Check if Playwright is available on this platform.
|
|
4
|
+
*/
|
|
5
|
+
function isPlaywrightAvailable() {
|
|
6
|
+
try {
|
|
7
|
+
if (process.platform === "android")
|
|
8
|
+
return false;
|
|
9
|
+
require.resolve("playwright");
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Discover the user's internship position ID.
|
|
18
|
+
* Tries JWT extraction first (no browser needed).
|
|
19
|
+
* Falls back to browser-based discovery via Playwright if available.
|
|
20
|
+
* On Android, uses JWT extraction only.
|
|
6
21
|
*/
|
|
7
22
|
export async function discoverPosition() {
|
|
8
23
|
ensureInstallDir();
|
|
9
24
|
console.log("=== Discovering internship position ID ===\n");
|
|
10
|
-
// Step 1: Try
|
|
11
|
-
|
|
12
|
-
|
|
25
|
+
// Step 1: Try extracting from saved token (no browser needed)
|
|
26
|
+
const token = loadToken();
|
|
27
|
+
if (token) {
|
|
28
|
+
const positionId = getPositionIdFromToken(token);
|
|
29
|
+
if (positionId) {
|
|
30
|
+
const worklogUrl = `https://student-api.kalvium.community/api/internships/worklogs/${positionId}`;
|
|
31
|
+
saveConfig({ position_id: positionId, worklog_api_url: worklogUrl });
|
|
32
|
+
console.log(`\n=== SUCCESS ===`);
|
|
33
|
+
console.log(`Position ID: ${positionId}`);
|
|
34
|
+
console.log(`Worklog API: ${worklogUrl}`);
|
|
35
|
+
console.log(`Saved to: ${CONFIG_FILE}`);
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
console.log(" Could not extract position ID from token.");
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
console.log(" No token found. Run `kalvium-worklog login` first.");
|
|
42
|
+
}
|
|
43
|
+
// Step 2: Fall back to browser-based discovery (if Playwright available)
|
|
44
|
+
if (!isPlaywrightAvailable()) {
|
|
45
|
+
console.log("\nERROR: Could not discover position ID.");
|
|
46
|
+
console.log("Playwright is not available on this platform.");
|
|
47
|
+
console.log("Make sure you have a valid token (run `kalvium-worklog login`).");
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
const { chromium } = await import("playwright");
|
|
51
|
+
console.log("\n1. Trying headless mode (existing session)...");
|
|
52
|
+
let captured = await discoverViaBrowser(chromium, true);
|
|
13
53
|
if (!captured.token) {
|
|
14
54
|
console.log(" No valid session. Opening browser for manual login...");
|
|
15
|
-
captured = await discoverViaBrowser(false);
|
|
55
|
+
captured = await discoverViaBrowser(chromium, false);
|
|
16
56
|
}
|
|
17
57
|
if (!captured.token) {
|
|
18
58
|
console.log("\nERROR: Could not capture token. Please log in and try again.");
|
|
19
59
|
return false;
|
|
20
60
|
}
|
|
21
61
|
console.log(` Token captured: ${captured.token.slice(0, 40)}...`);
|
|
22
|
-
// Step
|
|
62
|
+
// Step 3: Extract position ID from captured API URLs
|
|
23
63
|
const positionId = extractPositionId(captured.api_url ?? "");
|
|
24
64
|
if (!positionId) {
|
|
25
65
|
console.log("\nERROR: Could not determine position ID from API calls");
|
|
26
66
|
return false;
|
|
27
67
|
}
|
|
28
|
-
// Step
|
|
68
|
+
// Step 4: Save config
|
|
29
69
|
const worklogUrl = `https://student-api.kalvium.community/api/internships/worklogs/${positionId}`;
|
|
30
70
|
saveConfig({ position_id: positionId, worklog_api_url: worklogUrl });
|
|
31
71
|
console.log(`\n=== SUCCESS ===`);
|
|
@@ -34,7 +74,7 @@ export async function discoverPosition() {
|
|
|
34
74
|
console.log(`Saved to: ${CONFIG_FILE}`);
|
|
35
75
|
return true;
|
|
36
76
|
}
|
|
37
|
-
async function discoverViaBrowser(headless) {
|
|
77
|
+
async function discoverViaBrowser(chromium, headless) {
|
|
38
78
|
const captured = {};
|
|
39
79
|
const context = await chromium.launchPersistentContext(PROFILE_DIR, {
|
|
40
80
|
headless: false,
|
|
@@ -75,16 +115,25 @@ async function discoverViaBrowser(headless) {
|
|
|
75
115
|
}
|
|
76
116
|
else {
|
|
77
117
|
console.log("\n ========================================");
|
|
78
|
-
console.log(" Browser opened.
|
|
79
|
-
console.log("
|
|
80
|
-
console.log(" 2. Sign in with your Kalvium account");
|
|
81
|
-
console.log(" 3. Complete 2FA if prompted");
|
|
82
|
-
console.log(" 4. Wait — the script continues automatically");
|
|
118
|
+
console.log(" Browser opened. Auto-clicking 'Continue with Google'...");
|
|
119
|
+
console.log(" Please complete 2FA if prompted.");
|
|
83
120
|
console.log(" ========================================\n");
|
|
84
121
|
await page.goto("https://kalvium.community/internships", {
|
|
85
122
|
waitUntil: "domcontentloaded",
|
|
86
123
|
timeout: 120000,
|
|
87
124
|
});
|
|
125
|
+
// Auto-click "Continue with Google"
|
|
126
|
+
try {
|
|
127
|
+
const googleBtn = page.locator("text=Continue with Google").first();
|
|
128
|
+
const isVisible = await googleBtn.isVisible().catch(() => false);
|
|
129
|
+
if (isVisible) {
|
|
130
|
+
await googleBtn.click();
|
|
131
|
+
console.log(" Clicked 'Continue with Google'.");
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
// ignore
|
|
136
|
+
}
|
|
88
137
|
console.log(" Waiting for login to complete (up to 5 minutes)...");
|
|
89
138
|
for (let i = 0; i < 300; i++) {
|
|
90
139
|
if (captured.token && captured.api_url)
|
|
@@ -112,7 +161,6 @@ function extractPositionId(apiUrl) {
|
|
|
112
161
|
if (internshipsIdx === -1)
|
|
113
162
|
return null;
|
|
114
163
|
for (const part of parts.slice(internshipsIdx + 1)) {
|
|
115
|
-
// Position IDs are UUIDs (36 chars, 4 dashes)
|
|
116
164
|
if (part.length === 36 && part.split("-").length === 5) {
|
|
117
165
|
return part;
|
|
118
166
|
}
|