@wilm-ai/wilma-cli 1.6.1 → 2.0.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/LICENSE +21 -0
- package/README.md +57 -67
- package/dist/access.d.ts +12 -0
- package/dist/access.js +33 -0
- package/dist/agent-data.d.ts +496 -0
- package/dist/agent-data.js +578 -0
- package/dist/cli-args.d.ts +33 -0
- package/dist/cli-args.js +256 -0
- package/dist/cli-help.d.ts +2 -0
- package/dist/cli-help.js +141 -0
- package/dist/cli-output.d.ts +6 -0
- package/dist/cli-output.js +184 -0
- package/dist/config.js +63 -24
- package/dist/credentials.d.ts +69 -0
- package/dist/credentials.js +195 -0
- package/dist/downloads.d.ts +23 -0
- package/dist/downloads.js +105 -0
- package/dist/index.js +692 -1644
- package/dist/login-server.d.ts +52 -0
- package/dist/login-server.js +595 -0
- package/dist/mcp-tools.d.ts +23 -0
- package/dist/mcp-tools.js +235 -0
- package/dist/mcp.d.ts +1 -0
- package/dist/mcp.js +153 -0
- package/dist/output-json.d.ts +1 -0
- package/dist/output-json.js +26 -0
- package/dist/session-store.d.ts +7 -0
- package/dist/session-store.js +61 -0
- package/dist/tenant-search.d.ts +11 -0
- package/dist/tenant-search.js +127 -0
- package/dist/totp.d.ts +6 -0
- package/dist/totp.js +49 -0
- package/package.json +24 -8
package/dist/totp.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Accept either a bare base32 key or an otpauth:// URI and return the base32 key. */
|
|
2
|
+
export declare function parseTotpSecret(raw: string): string;
|
|
3
|
+
export declare const TOTP_PERIOD_MS = 30000;
|
|
4
|
+
/** The 30-second time step a moment falls in. */
|
|
5
|
+
export declare function totpCounter(timeMs?: number): number;
|
|
6
|
+
export declare function generateTOTP(secret: string, timeMs?: number): string;
|
package/dist/totp.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { createHmac } from "node:crypto";
|
|
2
|
+
/** Accept either a bare base32 key or an otpauth:// URI and return the base32 key. */
|
|
3
|
+
export function parseTotpSecret(raw) {
|
|
4
|
+
const value = raw.trim();
|
|
5
|
+
if (value.startsWith("otpauth://")) {
|
|
6
|
+
const url = new URL(value);
|
|
7
|
+
const secret = url.searchParams.get("secret");
|
|
8
|
+
if (!secret) {
|
|
9
|
+
throw new Error("No 'secret' parameter found in otpauth:// URI.");
|
|
10
|
+
}
|
|
11
|
+
return secret;
|
|
12
|
+
}
|
|
13
|
+
return value.replace(/[\s-]/g, "");
|
|
14
|
+
}
|
|
15
|
+
export const TOTP_PERIOD_MS = 30_000;
|
|
16
|
+
/** The 30-second time step a moment falls in. */
|
|
17
|
+
export function totpCounter(timeMs = Date.now()) {
|
|
18
|
+
return Math.floor(timeMs / TOTP_PERIOD_MS);
|
|
19
|
+
}
|
|
20
|
+
export function generateTOTP(secret, timeMs = Date.now()) {
|
|
21
|
+
// TOTP: RFC 6238 — HMAC-SHA1 based, 6-digit, 30-second period
|
|
22
|
+
const base32Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
|
23
|
+
// Decode base32 secret
|
|
24
|
+
const cleanSecret = secret.replace(/[\s=-]+/g, "").toUpperCase();
|
|
25
|
+
let bits = "";
|
|
26
|
+
for (const c of cleanSecret) {
|
|
27
|
+
const val = base32Chars.indexOf(c);
|
|
28
|
+
if (val === -1)
|
|
29
|
+
throw new Error(`Invalid base32 character: ${c}`);
|
|
30
|
+
bits += val.toString(2).padStart(5, "0");
|
|
31
|
+
}
|
|
32
|
+
const bytes = new Uint8Array(Math.floor(bits.length / 8));
|
|
33
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
34
|
+
bytes[i] = parseInt(bits.slice(i * 8, i * 8 + 8), 2);
|
|
35
|
+
}
|
|
36
|
+
const counter = totpCounter(timeMs);
|
|
37
|
+
const counterBuf = Buffer.alloc(8);
|
|
38
|
+
counterBuf.writeUInt32BE(Math.floor(counter / 0x100000000), 0);
|
|
39
|
+
counterBuf.writeUInt32BE(counter >>> 0, 4);
|
|
40
|
+
const hmac = createHmac("sha1", Buffer.from(bytes));
|
|
41
|
+
hmac.update(counterBuf);
|
|
42
|
+
const hash = hmac.digest();
|
|
43
|
+
const offset = hash[hash.length - 1] & 0x0f;
|
|
44
|
+
const code = ((hash[offset] & 0x7f) << 24) |
|
|
45
|
+
((hash[offset + 1] & 0xff) << 16) |
|
|
46
|
+
((hash[offset + 2] & 0xff) << 8) |
|
|
47
|
+
(hash[offset + 3] & 0xff);
|
|
48
|
+
return (code % 1000000).toString().padStart(6, "0");
|
|
49
|
+
}
|
package/package.json
CHANGED
|
@@ -1,31 +1,47 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wilm-ai/wilma-cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Read your children's Wilma (Finnish school system) from the terminal or an AI assistant: schedule, homework, exams, messages and news.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/aikarjal/wilmai.git",
|
|
9
|
+
"directory": "packages/wilma-cli"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://wilm.ai",
|
|
12
|
+
"bugs": "https://github.com/aikarjal/wilmai/issues",
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=20.18.1"
|
|
15
|
+
},
|
|
4
16
|
"type": "module",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
7
17
|
"bin": {
|
|
8
18
|
"wilmai": "dist/index.js",
|
|
9
19
|
"wilma": "dist/index.js"
|
|
10
20
|
},
|
|
11
21
|
"scripts": {
|
|
12
22
|
"build": "tsc -p tsconfig.json",
|
|
13
|
-
"lint": "
|
|
14
|
-
"test": "pnpm --filter @wilm-ai/wilma-client build && pnpm run build && node test/news-resources.mjs",
|
|
23
|
+
"lint": "tsc -p tsconfig.json --noEmit",
|
|
24
|
+
"test": "pnpm --filter @wilm-ai/wilma-client build && pnpm run build && node test/news-resources.mjs && node test/mcp-login.mjs && node test/mfa.mjs && node test/audit.mjs",
|
|
15
25
|
"start": "node dist/index.js",
|
|
16
26
|
"prepack": "pnpm --filter @wilm-ai/wilma-client build && pnpm --filter @wilm-ai/wilma-cli build",
|
|
17
|
-
"test:live": "tsc -p tsconfig.json && node test/live.spec.mjs"
|
|
27
|
+
"test:live": "tsc -p tsconfig.json && node test/live.spec.mjs",
|
|
28
|
+
"build:mcpb": "pnpm run build && node scripts/build-mcpb.mjs"
|
|
18
29
|
},
|
|
19
30
|
"dependencies": {
|
|
20
31
|
"@inquirer/prompts": "^5.3.8",
|
|
21
|
-
"@
|
|
32
|
+
"@modelcontextprotocol/sdk": "^1.32.0",
|
|
33
|
+
"@wilm-ai/wilma-client": "^1.6.0",
|
|
34
|
+
"zod": "^4.1.0"
|
|
22
35
|
},
|
|
23
36
|
"devDependencies": {
|
|
37
|
+
"@anthropic-ai/mcpb": "^2.1.2",
|
|
38
|
+
"esbuild": "^0.25.0",
|
|
24
39
|
"typescript": "^5.6.3"
|
|
25
40
|
},
|
|
26
41
|
"files": [
|
|
27
42
|
"dist",
|
|
28
|
-
"README.md"
|
|
43
|
+
"README.md",
|
|
44
|
+
"LICENSE"
|
|
29
45
|
],
|
|
30
46
|
"publishConfig": {
|
|
31
47
|
"access": "public"
|